I have a search field whose original width is small (because it looks better that way). However, when the user clicks on the search field, I want to make its width bigger by a certain amount. When the user clicks outside, I want to resize it to the original size. I also want to do all the resizes with animations.
Here is what I have so far:
#define kAddedWidth 85
@implementation ToolbarSearchField
- (id)initWithFrame: (NSRect)frameRect
{
self = [super initWithFrame: frameRect];
if (self) {
originalSize = self.frame.size.width;
}
return self;
}
- (void)awakeFromNib
{
[super awakeFromNib];
originalSize = self.frame.size.width;
}
- (BOOL)becomeFirstResponder
{
NSRect newFrame = NSMakeRect(self.frame.origin.x, self.frame.origin.y, originalSize + kAddedWidth, self.frame.size.height);
[[self animator] setFrame: newFrame];
return [super becomeFirstResponder];
}
- (BOOL)resignFirstResponder
{
NSRect newFrame = NSMakeRect(self.frame.origin.x, self.frame.origin.y, originalSize, self.frame.size.height);
[[self animator] setFrame: newFrame];
return [super resignFirstResponder];
}
@end
originalSize is an iVar.
The problem is that this isn't resizing anything. Clicking on the field or outside isn't doing a single bit.
I did some NSLog debugging and it seems that when I click on the field becomeFirstResponder
gets called and immediately after that resignFirstResponder
is called, nullifying the resize animation. However, the field is still active and blinking the insertion point. Have any ideas?
The Solution:
Thanks to Peter Hosey's answer, I managed to solve this. Here is my solution:
#define kAddedWidth (self.superview.bounds.size.width - self.frame.origin.x * 2 - originalSize)
@implementation ToolbarSearchField
- (id)initWithFrame: (NSRect)frameRect
{
self = [super initWithFrame: frameRect];
if (self) {
originalSize = self.frame.size.width;
}
return self;
}
- (void)awakeFromNib
{
[super awakeFromNib];
originalSize = self.frame.size.width;
}
- (void)textDidBeginEditing: (NSNotification*)notification
{
[super textDidBeginEditing: notification];
isEditing = YES;
NSRect newFrame = NSMakeRect(self.frame.origin.x, self.frame.origin.y, originalSize + kAddedWidth, self.frame.size.height);
[[self animator] setFrame: newFrame];
}
- (void)textDidEndEditing: (NSNotification*)notification
{
[super textDidEndEditing: notification];
isEditing = NO;
if ([self.stringValue isEqualToString: @""]) {
NSRect newFrame = NSMakeRect(self.frame.origin.x, self.frame.origin.y, originalSize, self.frame.size.height);
[[self animator] setFrame: newFrame];
}
}
- (void)mouseDown: (NSEvent*)theEvent
{
if (!isEditing) {
NSRect newFrame = NSMakeRect(self.frame.origin.x, self.frame.origin.y, originalSize + kAddedWidth, self.frame.size.height);
[[self animator] setFrame: newFrame];
}
[super mouseDown: theEvent];
}
Whenever the field is clicked and it isn't editing already, animate to a bigger size. Whenever the field ends editing, animate only if it doesn't have text. If it has text then it is better not to make the field smaller.