我尝试实现类似Xcode的搜索行为:如果您在搜索字段中输入内容,图标就会更改颜色。
我将 searchFieldDidStartSearching 和 searchFieldDidEndSearching 委托给控制器并更改图像。 问题在于图标的图像仅在窗口失去焦点时才会更改。
class ViewController: NSViewController {
@IBOutlet weak var searchField: NSSearchField!
func searchFieldDidStartSearching(_ sender: NSSearchField) {
print("\(#function)")
(searchField.cell as! NSSearchFieldCell).searchButtonCell?.image = NSImage.init(named: "NSActionTemplate")
}
func searchFieldDidEndSearching(_ sender: NSSearchField) {
print("\(#function)")
(searchField.cell as! NSSearchFieldCell).searchButtonCell?.image = NSImage.init(named: "NSHomeTemplate")
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override var representedObject: Any? {
didSet {
// Update the view, if already loaded.
}
}
}
预先感谢您的任何想法/建议。
答案 0 :(得分:0)
如您所见,当您在视图内单击时,它仍然集中在搜索文本字段上(因为单击它下方仍可以在其中键入内容)。由于更改图像失去焦点时会亮起,因此您应该检查是否在文本字段之外单击。
答案 1 :(得分:0)
通过子类化 NSSearchFieldCell 解决问题,并将此类分配给字段的单元格。
答案 2 :(得分:0)
虽然我不知道原因,但是它起作用:
NSApp.mainWindow?.resignMain()
NSApp.mainWindow?.becomeMain()
这是整个代码:
class MyViewController: NSViewController {
private lazy var searchField: NSSearchField = {
let searchField = NSSearchField(string: "")
if let searchButtonCell = searchField.searchButtonCell {
searchButtonCell.setButtonType(.toggle)
let filterImage = #imageLiteral(resourceName: "filter")
searchButtonCell.image = filterImage.tinted(with: .systemGray)
searchButtonCell.alternateImage = filterImage.tinted(with: .systemBlue)
}
searchField.focusRingType = .none
searchField.bezelStyle = .roundedBezel
searchField.delegate = self
return searchField
}()
...
}
extension MyViewController: NSSearchFieldDelegate {
func searchFieldDidStartSearching(_ sender: NSSearchField) {
sender.searchable = true
}
func searchFieldDidEndSearching(_ sender: NSSearchField) {
sender.searchable = false
}
}
extension NSSearchField {
var searchButtonCell: NSButtonCell? {
(self.cell as? NSSearchFieldCell)?.searchButtonCell
}
var searchable: Bool {
get {
self.searchButtonCell?.state == .on
}
set {
self.searchButtonCell?.state = newValue ? .on : .off
self.refreshSearchIcon()
}
}
private func refreshSearchIcon() {
NSApp.mainWindow?.resignMain()
NSApp.mainWindow?.becomeMain()
}
}
extension NSImage {
func tinted(with color: NSColor) -> NSImage? {
guard let image = self.copy() as? NSImage else { return nil }
image.lockFocus()
color.set()
NSRect(origin: NSZeroPoint, size: self.size).fill(using: .sourceAtop)
image.unlockFocus()
image.isTemplate = false
return image
}
}
答案 3 :(得分:0)
我遇到了同样的问题。一个简单的覆盖为我解决了这个问题
extension NSSearchField{
open override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
}
}