NSSearchField中的可点击搜索图标和淡化背景

时间:2012-12-10 08:55:13

标签: objective-c xcode macos cocoa nssearchfield

我想制作一个NSSearchField,就像Ecoute 3.0中的那个。 搜索字段中的搜索图标应该是可点击的,如果单击它,则展开和折叠。

enter image description here enter image description here

你怎么能做到这一点? 我搜索了文档,但没有提出任何有用的信息。 我可以用动画代理实现扩展,所以很清楚。

另一件事是背景在扩展/折叠时淡入/淡出。 我怎样才能做到这一点?

我会感谢任何建议,示例代码等。

修改

好的,我自己找到了第一部分。

- (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: setter方法中,我执行以下操作:

NSRect newRect = self.frame;

if (_isCollapsed) {
    newRect.size.width = kCollapsedWidth;
} else {
    newRect.size.width = kEXpandedWidth;
}

[[self animator] setFrameSize:newRect.size];

但由于某种原因,当NSSearchField获得或失去焦点时,帧被重置为初始大小,即Interface Builder中设置的大小。

谁能告诉我为什么?

修改

我也解决了这个问题。这是自动布局,搞砸了动画。 现在,唯一剩下的就是background-alpha,它应该改变。 我可以重绘整个事情,但还有另一个解决方案,我只能修改背景和取消按钮的alpha吗?

2 个答案:

答案 0 :(得分:1)

我想做类似的事情。 ITSearchField非常可靠。但是,一旦获得焦点,我希望扩展搜索字段。正如人们可能很快发现的那样,NSSearchfield由许多组件和层组成。

以下是我为了让它发挥作用而写的内容...... 注意:它适用于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或任何您想要调用的类。

享受!

答案 1 :(得分:0)

我最终重新绘制了背景。像这样,我能够设置它的alpha。

源代码可在Github上找到:

https://github.com/iluuu1994/ITSearchField