Кликабельный значок поиска в 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];

Но по какой-то причине кадр сбрасывается до исходного размера, установленного в Interface Builder, когда NSSearchField получает или теряет фокус.

Кто-нибудь может сказать мне, почему?

ИЗМЕНИТЬ

Я тоже решил эту проблему. Это был автоматический макет, который испортил анимацию. Теперь единственное, что осталось, это background-alpha, который должен измениться. Я мог бы перерисовать все это, но есть ли другое решение, в котором я мог бы просто изменить альфу только фона и кнопки отмены?


person IluTov    schedule 10.12.2012    source источник


Ответы (2)


Я хотел сделать что-то подобное. ITSearchField очень надежный и приятный. Однако я хотел расширить поле поиска после того, как оно получило фокус. Как можно быстро выяснить, поле NSSearch состоит из множества компонентов и слоев.

Вот что я написал, чтобы заставить его работать... Примечание. Это работает на 10.7 или выше. Также вы должны подключить ограничение макета ширины поля поиска в IB к выходу.

.h

@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 или как вы хотите его назвать.

Наслаждаться!

person Arvin    schedule 04.01.2013
comment
Спасибо за ваше предложение. Я очень доволен ITSearchField, потому что он лучше всего соответствует моим требованиям. Ваше здоровье ;) - person IluTov; 05.01.2013

В итоге я перерисовал фон. Вот так я смог установить альфу.

Исходный код доступен на Github:

https://github.com/iluuu1994/ITSearchField

person IluTov    schedule 30.12.2012