OSX Cocoa NSSearchField 清除按钮没有响应点击

OSX Cocoa NSSearchField clear button not responding to click

我放置了一个 NSSearchField 并将其边框设置为 none,我发现清除按钮不可点击 a.k.a。单击时没有响应。如果我再次设置边框,它工作正常。

我已经调试了几个小时,发现当我将边框设置为 none 时,文本编辑器的宽度会扩大并遮盖(覆盖)清除按钮。

截图

查看层级调试截图

重现步骤:

  1. 创建空 cocoa project/app
  2. 放置一个 NSSearchField
  3. 将边框设置为 none
  4. 运行 应用程序,填写搜索字段并尝试点击清除按钮

这是一个错误吗?还是它打算那样做?

注意:cocoa 开发新手

我遇到了这个问题,并将其视为 Cocoa 中的错误。但是很容易在自定义控件或视图控制器中修复。只需在界面生成器中保留文本字段的边框,然后通过新的 CALayer 取消边框。例如:

class ViewController: NSViewController {


@IBOutlet weak var searchField: NSSearchField!

override func viewDidLoad() {
    super.viewDidLoad()

    let maskLayer = CALayer()
    searchField.layer = maskLayer
    maskLayer.backgroundColor = searchField.backgroundColor?.CGColor
}
}

如您所见,我只是在新图层中恢复控件颜色,没有保留任何其他内容。它并不完美,但至少提供了一个良好的开端。

在代码创建的 NSSearchField 中遇到了同样的问题。通过覆盖子类中的 NSSearchFieldCell 方法解决了它:

 - (void)selectWithFrame:(NSRect)aRect inView:(NSView *)controlView editor:(NSText *)textObj delegate:(id)anObject start:(NSInteger)selStart length:(NSInteger)selLength
{
    NSRect newRect = aRect;
    newRect.size.width -= (NSWidth([self searchButtonRectForBounds:aRect]) + NSWidth([self cancelButtonRectForBounds:aRect]));
    [super selectWithFrame:newRect inView:controlView editor:textObj delegate:anObject start:selStart length:selLength];
}

鼠标点击字段的文本区域后调用该方法。它似乎也是设置插入点颜色的好地方。

几乎是正确的。您还应该从 rect.origin.x 中删除 searchButtonWidth 以向后偏移 rect。

而且我还添加了一些逻辑来使这些 "tricks" 仅在需要时使用。

override func select(withFrame rect: NSRect, in controlView: NSView, editor textObj: NSText, delegate: Any?, start selStart: Int, length selLength: Int) {

    var newRect = rect

    if !isBordered || isBezeled {
        let cancelButtonWidth = NSWidth(cancelButtonRect(forBounds: rect))
        let searchButtonWidth = NSWidth(searchButtonRect(forBounds: rect))

        newRect.size.width -= (cancelButtonWidth + searchButtonWidth)
        newRect.origin.x += searchButtonWidth
    }
    super.select(withFrame: newRect, in: controlView, editor: textObj, delegate: delegate, start: selStart, length: selLength)
}

创建子类后,只需在 IB 身份检查器中将其设置为 NSSearchFieldCell 实例即可。