auto resize textfield when textfield is editing - macos

I have problem with my project on Mac OS. I have a textfield, I want to change size it automatically when textfield is editing!Please suggest me a way to solve this. Thanks so much!

You need to set an object as the delegate of your NSTextField. As NSTextField is a subclass of NSControl, it will call the -controlTextDidChange: method on your object if you implement it.
#interface MyObject : NSObject
{
IBOutlet NSTextField* textField;
}
#end
#implementation MyObject
- (void)awakeFromNib
{
[textField setDelegate:self];
}
- (void)controlTextDidChange:(NSNotification *)aNotification
{
if([notification object] == textField)
{
textField.font = [UIFont fontWithName:#"HelveticaNeue-Light" size:14];
}
}
#end

Related

-[NSTextView setTag:] does not exist... how can I identify different text views?

There does not seem to be a setTag: for NSTextView.
So if I have multiple NSTextViews, how can I access them without creating iVars for each one?
I know a possibility could be through the delegate... but I have the same problem there: how to identify which NSTextView is messaging?
You can add your own tag property for NSTextView in category and make it editable from Xcode Interface Builder
IB_DESIGNABLE
#interface NSTextView (Tag)
#property (strong, readwrite, nonatomic, nullable) IBInspectable NSString *myTag;
#end
const NSMutableDictionary* tagsMap;
#implementation NSTextView (Tag)
- (void) dealloc {
tagsMap[[NSValue valueWithNonretainedObject:self]] = nil;
}
- (void) setMyTag:(NSString *)myTag {
if (tagsMap == nil) {
tagsMap = [NSMutableDictionary new];
}
tagsMap[[NSValue valueWithNonretainedObject:self]] = myTag;
}
- (NSString*) myTag {
return tagsMap[[NSValue valueWithNonretainedObject:self]];
}
#end
Just adding an approach... simple... but dirty.
When I instantiate say 2 NSTextViews... I set each one with a different fontSize: (49 and 50) and so I can identify them that way.
-(void)textDidChange:(NSNotification *)notification {
NSTextView* textView = (NSTextView *)[notification object];
if ([textView.font isEqualTo:[NSFont systemFontOfSize:49]]) {
NSLog(#"1");
} else if ([textView.font isEqualTo:[NSFont systemFontOfSize:50]])
{
NSLog(#"2");
}
}

ARC: How do you release a WindowController when the user closes the Window?

I'm trying to translate some old code to ARC. The old code does this in the WindowController:
#interface PreferencesController () <NSWindowDelegate>
#end
#implementation PreferencesController
-(void)windowWillClose:(NSNotification*) notification {
[self autorelease];
}
#end
My AppDelegate has a strong pointer to the WindowController:
#property(strong) PreferencesController* preferencesCtrl;
In PreferencesController, do I need to declare a (weak) pointer back to the AppDelegate, and then do something like this:
-(void) windowWillClose:(NSNotification *)notification {
[[self appDelegate] setPreferencesCtrl:nil];
}
Well, your thoughts are right.
But I can give you make it more simple.
Set your application delegate as NSWindowDelegate.
#interface AppDelegate : NSObject <NSApplicationDelegate, NSWindowDelegate>
#property (strong) PreferencesController* preferencesCtrl;
#end
#implementation AppDelegate
- (void)doAction
{
// create window
// ...
self.preferencesCtrl.window.delegate = self; // set window delegate
}
- (void)windowWillClose:(NSNotification *)notification
{
self.preferencesCtrl=nil;
}
#end
UPD
Since you are already using NSWindowDelegate methods, I suggest you to create another delegate protocol, say PreferenceControllerDelegate
//in PreferenceController.h before class interface
#class PreferenceControllerDelegate
#protocol PreferenceControllerDelegate <NSObject>
- (void)preferenceControllerWindowWillClose:(PreferenceControllerDelegate *)sender;
#end
#interface PreferenceController : NSWindowController
//...
#property (nonatomic,weak) id<PreferenceControllerDelegate> delegate;
//...
#end
That would be much proper.
Try using #autoreleasepool to force an immediate dealloc when you nil the pointer.
-(void) windowWillClose:(NSNotification *)notification {
//[[self appDelegate] setPreferencesCtrl:nil];
#autoreleasepool {
[[NSApp delegate] setPreferencesCtrl:nil];
}
}
You can also access the app delegate through the NSApp singleton using NSApp.delegate, which is [[NSApplication sharedApplication] delegate], though I guess you'd have to typecast it to avoid a warning. Either way.

UILabel subclass

I know that this is a newbie question but I am a newbie so here goes:
I wish to use Chalkduster font quite a lot throughout my app (buttons, labels etc) and have tried subclassing UILabel to achieve this. I have the following in Default.h:
#import <UIKit/UIKit.h>
#interface Default : UILabel
{
UILabel *theLabel;
}
#property (nonatomic, strong) IBOutlet UILabel *theLabel;
#end
and this in my .m:
#import "Default.h"
#implementation Default
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
UIFont *custom = [[UIFont alloc] init];
custom = [UIFont fontWithName:#"Chalkduster" size:18];
self.font = custom;
NSLog(#"h");
}
return self;
}
#end
When I change the class in interface builder and run, I'm not seeing the Chalkduster font. I'd appreciate a hand in getting this set up as I believe it will save me a lot of time.
Cheers.
Some problems to fix:
1) You're mixing up the idea of Default being a label and Default containing a label. To subclass, get rid of the property inside your class and make your changes to self rather than theLabel (inside the if (self) { section).
2) Anything you code after an unconditional return isn't going to get executed...and I'm surprised the compiler didn't complain about those statements.
Edit: ...and one more thing that just dawned on me.
3) If you're loading from a xib or storyboard, the initialization is done by initWithCoder: instead of initWithFrame:, so:
- (id)initWithCoder:(NSCoder *)coder {
self = [super initWithCoder:coder];
if (self) {
self.font = [UIFont fontWithName:#"Chalkduster" size:18];
}
return self;
}
First of all I don't think that You're subclassing UILabel correctlly. So I made tutorial for You explaining how to do it. You don't need to IBOutlet object which is subclassed. JUST CALL IT WITH SELF. for example: self.font = ... If You want to subclass UILabel do this:
Create new class with title myLabel like this:
.h
#import <UIKit/UIKit.h>
#interface MyLabel : UILabel {
}
#end
.m
#import "MyLabel.h"
#implementation MyLabel
-(void)awakeFromNib {
UIFont *custom = [[UIFont alloc] init];
custom = [UIFont fontWithName:#"Chalkduster" size:18];
self.font = custom;
}
#end
Now select Your label in storyboard and go to indentity inspector and in Custom Class select created class above. Like this:
Output:
Note: Don't forget to release custom because You are allocating it.
Move the return self; three lines down. You return from the init method before you do your custom initialization.
Edit to reflect new information from comment:
When deserializing the view from a nib you also have to override initWithCoder:

NSTableView not Populating

I've been trying to get this NSTableView to populate for the last 7 hours. I am trying to get a list of all the currently running application and put them into an NSTableView. Eventually I would like to parse the resultes and organize the PID in one column and the Application Bundle in the other. I am getting an EXC_BAD_ACCESS error on " return [listOfWindows objectAtIndex:row];" I am currently using Xcode 4.3.2 and running OS X Lion 10.7.4. Thanks in advance everyone!
#interface AppDelegate : NSObject <NSApplicationDelegate>
{
IBOutlet NSMenu *statusMenu;
IBOutlet NSButton *button;
IBOutlet NSWindow *menuWindow;
IBOutlet NSTableView *proTable;
NSArray *listOfWindows;
IBOutlet NSArrayController *arrayController;
AppDelegate *mainMenu;
NSWorkspace *workSpace;
NSStatusItem *statusItem;
}
#property (assign) IBOutlet NSWindow *window;
-(IBAction)loadConfig:(id)sender;
#end
#import "AppDelegate.h"
#implementation AppDelegate
#synthesize window = _window;
- (void) awakeFromNib
{
[[NSDistributedNotificationCenter defaultCenter] addObserver:self
selector:#selector(loadMenu:)
name:#"WhiteBox"
object:nil];
[self addStatusItem];
//[proTable setDataSource:self];
listOfWindows = [[NSWorkspace sharedWorkspace] runningApplications];
NSLog(#"index %#", listOfWindows);
int y = 0;
y = [listOfWindows count];
NSLog(#"y = %d", y);
[proTable setAllowsMultipleSelection:YES];
}
-(void)applicationWillTerminate
{
NSLog(#"Will Terminate");
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
}
-(void)applicationDidResignActive:(NSNotification *)notification
{
NSLog(#"Resign Active");
}
-(void) addStatusItem
{
//Create a variable length status item from the system statusBar
statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength];
[statusItem retain];
//Set a Title for it
[statusItem setTitle:#"Status Item"];
//Set an Image and an alternate image
//[statusItem setImage:[NSImage imageNamed:#"lnc"]];
//[statusItem setAlternateImage: [NSImage imageNamed:#"status"]];
//Add a Tool Tip
[statusItem setToolTip:#"Status Item Tooltip"];
//Choose to highlight the item when clicked
[statusItem setHighlightMode:YES];
//To Trigger a method on click use the following two lines of code
[statusItem setMenu:statusMenu];
//[statusItem setAction:#selector(loadMenu:)];
}
-(IBAction)loadConfig:(id)sender
{
if(! [menuWindow isVisible] )
{
[menuWindow makeKeyAndOrderFront:sender];
} else {
[menuWindow performClose:sender];
}
}
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView
{
return [listOfWindows count];
}
- (id)tableView:(NSTableView *)tableView
objectValueForTableColumn:(NSTableColumn *)tableColumn
row:(NSInteger)row
{
return [listOfWindows objectAtIndex:row];
}
#end
What object is the table view's data source? I don't see any object in the source you posted as implementing the NSTableViewDataSource protocol.
Further, have you tried putting breakpoints in the various data source methods to see if the debugger stops in them? If not, it's usually a good sign that your data source isn't connected to your table view.
I got: -[NSRunningApplication copyWithZone:]: unrecognized selector error when I ran your code. This could be fixed by changing your return line in tableView:objectValueForTableColumn:row: to
return [[listOfWindows objectAtIndex:row]localizedName];
NSRunningApplication doesn't conform to NSCopying, so I don't know if you can put instances of that class in a table view. However, you can get its properties like localizedName, processIdentifier, and bundleIdentifier.
I've run into this problem before with classes that don't implement NSCopying, I'd be happy to know if anyone knows a way to use these classes in table views or outline views.

NSTextView value changed

I'm pretty new to mac development (coming from a web and iOS background) and I can't work out how I could get a notification every time the value of an NSTextView changes. Any ideas?
Ups I just saw that you want a callback from NSTextView and not NSTextField
Just add in the header of the object which should be the delegate the protocol
#interface delegateAppDelegate : NSObject <NSApplicationDelegate, NSTextViewDelegate> {
NSWindow *window;
}
After that you add a method like
-(void)textDidChange:(NSNotification *)notification {
NSLog(#"Ok");
}
Make sure you connected the delegate property of the NSTextView (not NSScrollView) with the object which should receive the delegate
Here's the solution:
NSTextView *textView = ...;
#interface MyClass : NSObject<NSTextStorageDelegate>
#property NSTextView *textView;
#end
MyClass *myClass = [[MyClass alloc] init];
myClass.textView = textView;
textView.textStorage.delegate = myClass;
#implementation MyClass
- (void)textStorageDidProcessEditing:(NSNotification *)aNotification
{
// self.textView.string will be the current value of the NSTextView
// and this will get invoked whenever the textView's value changes,
// BOTH from user changes (like typing) or programmatic changes,
// like textView.string = #"Foo";
}
#end
set the nstextfield's delegate. in the .h file of the delegate you add the delegate protocol
In the .m file you add a method like -(void)controlTextDidChange:(NSNotification *)obj {
NSLog(#"ok");
}
I hope that helps
Set the delegate and then use
- (void) controlTextDidChange: (NSNotification *) notification
{
}

Resources