1

尝试在 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
    }
}
4

0 回答 0