尝试在 URL 验证 NSTextField 中绘制警告图像,以防 URL 错误。一切正常,但我不确定我是否正在与 API 作斗争,还有其他方法。我正在调用 noteFocusRingMaskChanged 来重绘键盘焦点环,abortEditing + selectWithFrame 来重绘 textView。
中间图像显示我无法重绘 NSTextView 链接到图像
import Foundation
class URLValidationTextFieldCell: NSTextFieldCell {
let spaceForImage : CGFloat = 22
var isValid = false {
didSet {
if let textField = controlView as? NSTextField {
if (textField.isFirstResponder()) {
let string = textField.stringValue
textField.noteFocusRingMaskChanged()
textField.abortEditing()
if let textView = (controlView?.window?.fieldEditor(false, forObject: nil) as? NSTextView) {
let range = textView.selectedRange()
textView.insertText(string)
textField.selectWithFrame(frameRectForBounds(), editor: textView, delegate: textField, start: range.location, length: range.length)
}
} else {
textField.needsDisplay = true
}
}
}
}
func frameRectForBounds() -> NSRect {
return isValid ? (controlView?.bounds)! : NSIntegralRect(NSOffsetRect(NSInsetRect((controlView?.bounds)!, spaceForImage / 2, 0), -spaceForImage / 2 , 0))
}
func rectForImage(cellFrame: NSRect) -> NSRect {
if (isValid) {
return NSZeroRect
} else {
var rect = frameRectForBounds()
rect.origin.x = rect.size.width + 4
rect.size.width = spaceForImage - 4
return rect
}
}
override func drawInteriorWithFrame(cellFrame: NSRect, inView controlView: NSView) {
super.drawInteriorWithFrame(frameRectForBounds(), inView: controlView)
}
override func editWithFrame(aRect: NSRect, inView controlView: NSView, editor textObj: NSText, delegate anObject: AnyObject?, event theEvent: NSEvent) {
super.editWithFrame(frameRectForBounds(), inView: controlView, editor: textObj, delegate: anObject, event: theEvent)
}
override func selectWithFrame(aRect: NSRect, inView controlView: NSView, editor textObj: NSText, delegate anObject: AnyObject?, start selStart: Int, length selLength: Int) {
super.selectWithFrame(frameRectForBounds(), inView: controlView, editor: textObj, delegate: anObject, start: selStart, length: selLength)
}
override func drawWithFrame(cellFrame: NSRect, inView controlView: NSView) {
drawImage(rectForImage(cellFrame))
super.drawWithFrame(frameRectForBounds(), inView: controlView)
}
override func drawFocusRingMaskWithFrame(cellFrame: NSRect, inView controlView: NSView) {
super.drawFocusRingMaskWithFrame(frameRectForBounds(), inView: controlView)
}
func drawImage(aRect: NSRect) {
let image = NSImage(named: NSImageNameCaution)!
image.size = NSSize(width: 16, height: 16)
NSGraphicsContext.saveGraphicsState()
NSGraphicsContext.currentContext()?.imageInterpolation = NSImageInterpolation.High
image.drawInRect(aRect, fromRect: NSZeroRect, operation:NSCompositingOperation.CompositeSourceOver, fraction: 1.0, respectFlipped: true, hints: [:])
NSGraphicsContext.restoreGraphicsState()
}
}
extension NSTextField {
func isFirstResponder() -> Bool {
if let _ = window?.fieldEditor(false, forObject: nil) {
if let textView = window?.firstResponder as? NSTextView {
if (isEqualTo(textView.delegate)) {
return true
}
}
}
return false
}
}