0

我想做一个 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: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 和取消按钮?

4

2 回答 2

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 中的 Search Field 控件的类设置为 MySearchField 或任何您想调用的名称。

享受!

于 2013-01-04T16:43:48.560 回答
0

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

源代码在 Github 上可用:

https://github.com/iluuu1994/ITSearchField

于 2012-12-30T13:04:11.960 回答