NSTextField disappears after subclass

I have subclassed NSTextField with the following code:

import Cocoa class CustomSearchField: NSTextField { override func draw(_ dirtyRect: NSRect) { self.wantsLayer = true let textFieldLayer = CALayer() self.layer = textFieldLayer self.backgroundColor = NSColor.white self.layer?.backgroundColor = CGColor.white self.layer?.borderColor = CGColor.white self.layer?.borderWidth = 0 super.cell?.draw(withFrame: dirtyRect, in: self) } } class CustomSearchFieldCell: NSTextFieldCell { override func drawingRect(forBounds rect: NSRect) -> NSRect { let minimumHeight = self.cellSize(forBounds: rect).height let newRect = NSRect(x: rect.origin.x + 25, y: (rect.origin.y + (rect.height - minimumHeight) / 2) - 4, width: rect.size.width - 50, height: minimumHeight) return super.drawingRect(forBounds: newRect) } } 

It all works fine, and he drew my NSTextField the way I wanted. The only problem is that as soon as I make some part of the interface the first responder (by clicking outside NSTextField), the text inside the NSTextField (placeholder or filled text) disappears. As soon as I click on it again, it disappears. I’ve been looking for silence for some time, but I can’t understand why this is happening. I just want the text to be visible all the time, instead of fading in and out.

This is due to CALayer, which I add to fulfill my style.

Whenever I run the same settings from viewDidLoad in a text box, it works like a charm. For example:

 class ViewController: NSViewController { @IBOutlet weak var searchField: NSTextField! override func viewDidLoad() { initCustomSearchField() } private func initCustomSearchField() { searchField.wantsLayer = true let textFieldLayer = CALayer() searchField.layer = textFieldLayer searchField.backgroundColor = NSColor.white searchField.layer?.backgroundColor = CGColor.white searchField.layer?.borderColor = CGColor.white searchField.layer?.borderWidth = 0 searchField.delegate = self } } 
+7
cocoa swift subclass nstextfield
source share
1 answer

draw method really should be used to draw a view that does not set properties. And for your problem, don't set self.layer to directly use sublayer .

My suggestion for your code:

 class CustomTextField :NSTextField { override init(frame frameRect: NSRect) { super.init(frame: frameRect) setupView() } required init?(coder: NSCoder) { super.init(coder: coder) setupView() } func setupView(){ textColor = .green } } class CustomTextFieldCell: NSTextFieldCell { override init(textCell string: String) { super.init(textCell: string) setupView() } required init(coder: NSCoder) { super.init(coder: coder) setupView() } func setupView(){ backgroundColor = .red } override func drawingRect(forBounds rect: NSRect) -> NSRect { let newRect = NSRect(x: (rect.width - rect.width/2)/2, y: 0, width: rect.width/2, height: 20) return super.drawingRect(forBounds:newRect) } override func draw(withFrame cellFrame: NSRect, in controlView: NSView) { super.draw(withFrame: cellFrame, in: controlView) controlView.layer?.borderColor = NSColor.white.cgColor controlView.layer?.borderWidth = 2 } } 

enter image description here

+5
source share

All Articles