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

https://github.com/iluuu1994/ITSearchField

Я хотел сделать что-то подобное. 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 или как хотите, чтобы он назывался.

Наслаждайтесь!

Другие вопросы по тегам