Кликабельный значок поиска в NSSearchField и исчезающий фон
Я хотел бы создать NSSearchField, как в Ecoute 3.0. Значок поиска в поле поиска должен быть кликабельным, раскрываться и сворачиваться при нажатии на него.
Как вы можете достичь этого? Я искал документацию, но не нашел ничего полезного. Я мог бы реализовать расширение с помощью прокси аниматора, так что это понятно.
Другое дело, что фон исчезает / исчезает, когда он расширяется / разрушается. Как мне этого добиться?
Буду благодарен за любые советы, примеры кода и т. Д.
РЕДАКТИРОВАТЬ
Хорошо, я сам нашел первую часть.
- (void) resetSearchButtonCell {
NSButtonCell *c= [[NSButtonCell alloc] init];
[c setButtonType:NSMomentaryChangeButton]; // configure the button
[c setBezelStyle:NSRegularSquareBezelStyle]; // configure the button
[c setBordered:NO];
[c setBezeled:NO];
[c setEditable:NO];
[c setImagePosition:NSImageOnly];
[c setImage:[NSImage imageNamed:@"search"]];
[c setAlternateImage:[NSImage imageNamed:@"search-pushed"]];
[c setTarget:self];
[c setAction:@selector(_search:)];
[self setSearchButtonCell:c];
}
Теперь я сделал собственность isCollapsed
который я переключаю в _search:
, И в setIsCollapsed:
Метод установки я делаю следующее:
NSRect newRect = self.frame;
if (_isCollapsed) {
newRect.size.width = kCollapsedWidth;
} else {
newRect.size.width = kEXpandedWidth;
}
[[self animator] setFrameSize:newRect.size];
Но по какой-то причине кадр сбрасывается до первоначального размера, установленного в Интерфейсном Разработчике, когда NSSearchField получает или теряет фокус.
Кто-нибудь может сказать мне, почему?
РЕДАКТИРОВАТЬ
Я тоже решил эту проблему. Это была автоматическая разметка, которая испортила анимацию. Теперь единственное, что осталось - это фоновая альфа, которая должна измениться. Я мог бы перерисовать всю вещь, но есть ли другое решение, где я мог бы просто изменить альфа только фона и кнопки отмены?
2 ответа
В итоге я перерисовал фон. Таким образом я смог установить альфу этого.
Исходный код доступен на Github:
Я хотел сделать что-то подобное. ITSearchField очень солидный и приятный. Однако я хотел расширить поле поиска, как только оно получило фокус. Как можно быстро выяснить, поле NSSearch состоит из множества компонентов и слоев.
Вот что я написал, чтобы заставить его работать... Примечание: он работает на 10.7 или выше. Также к выходу необходимо подключить ограничение макета ширины элемента управления поля поиска в IB.
.час
@interface MySearchField : NSSearchField
@end
.m
#pragma mark - Implementation: Search Field Control
@interface MySearchField()
@property (readwrite, nonatomic, getter=isExpanded) BOOL expand;
@property (readwrite, nonatomic, getter=hasFocusRing) BOOL focusRing;
@property (readwrite, strong, nonatomic) NSTimer *expandTimer;
@property (readwrite, strong, nonatomic) IBOutlet NSLayoutConstraint *widthConstraint;
@property (readwrite, nonatomic) CGFloat searchWidth;
@end
static NSTimeInterval const kSearchFieldTime = 0.5;
@implementation MySearchField
@synthesize expand, focusRing;
@synthesize expandTimer, searchWidth;
@synthesize widthConstraint;
#pragma mark Timer Methods:
- (void) resizeSearchField {
if ( self.hasFocusRing ) {
if ( !self.isExpanded ) {
self.searchWidth = self.widthConstraint.constant;
[[self.widthConstraint animator] setConstant:(self.searchWidth * 2)];
self.expand = YES;
} } else {
if ( (self.isExpanded) &&
((!self.stringValue) || ([self.stringValue isEqualToString:@""])) ) {
[[self.widthConstraint animator] setConstant:self.searchWidth];
self.expand = NO;
} }
}
- (void) stopTimer {
if ( self.expandTimer )
[self.expandTimer invalidate];
self.expandTimer = nil;
}
- (void) startTimer {
[self stopTimer];
SEL resizeSelector = @selector(resizeSearchField);
NSMethodSignature *expandSignature = [MySearchField instanceMethodSignatureForSelector:resizeSelector];
NSInvocation *expandInvocation = [NSInvocation invocationWithMethodSignature:expandSignature];
[expandInvocation setSelector:resizeSelector];
[expandInvocation setTarget:self];
self.expandTimer = [NSTimer scheduledTimerWithTimeInterval:kSearchFieldTime invocation:expandInvocation repeats:NO];
}
#pragma mark Override Methods:
- (void) noteFocusRingMaskChanged {
self.focusRing = !NSEqualRects(NSZeroRect, self.focusRingMaskBounds);
[self startTimer];
[super noteFocusRingMaskChanged];
}
@end
Хорошо, это действительно так. Вы получите уведомление при смене кольца фокусировки и запустите метод быстрого таймера. Таймер необходим, когда вы нажимаете кнопку отмены в поле поиска, которая сбрасывает элемент управления. Единственное, что делает таймер - это запускает метод resizeSearchField.
Обновление: О да, не забудьте установить класс элемента управления "Поле поиска" в IB на MySearchField или как хотите, чтобы он назывался.
Наслаждайтесь!