swift 具有错误文本支持的UITextField。在UITextField下面绘制错误文本。

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了swift 具有错误文本支持的UITextField。在UITextField下面绘制错误文本。相关的知识,希望对你有一定的参考价值。

## Demo

![Demo](http://i.imgur.com/GkIRCxb.gif)
import Foundation
import UIKit

class UIErrorTextField : UITextField {
  private let bgView = UIView()
  private var textFieldHeight = CGFloat(40)
  private var errorTextHeight = CGFloat(12)
  private let errorTextPadding = CGFloat(2)

  var errorFont = UIFont.systemFontOfSize(12) {
    didSet {
      invalidateErrorTextContentSize()
    }
  }
  var errorText: String? {
    didSet {
      setNeedsDisplay()
    }
  }
  var errorTextColor = UIColor.blackColor() {
    didSet {
      setNeedsDisplay()
    }
  }

  required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    setup()
  }

  override init(frame: CGRect) {
    super.init(frame: frame)
    setup()
  }

  private func setup() {
    clipsToBounds = true
    borderStyle = .None
    let errorTextBounds = measureText("TEST", attributes: [NSFontAttributeName: errorFont])
    errorTextHeight = errorTextBounds.height
    setupBackgroundView()
  }

  override func intrinsicContentSize() -> CGSize {
    return CGSize(width: self.frame.width, height: calculateHeight())
  }

  override func editingRectForBounds(bounds: CGRect) -> CGRect {
    return offsetRectForEditing(super.editingRectForBounds(bounds))
  }

  override func textRectForBounds(bounds: CGRect) -> CGRect {
    return offsetRectForEditing(super.textRectForBounds(bounds))
  }

  override func leftViewRectForBounds(bounds: CGRect) -> CGRect {
    return offsetRectForEdgeView(super.leftViewRectForBounds(bounds))
  }

  override func rightViewRectForBounds(bounds: CGRect) -> CGRect {
    return offsetRectForEdgeView(super.rightViewRectForBounds(bounds))
  }

  override func drawRect(rect: CGRect) {
    bgView.frame.size.width = rect.width
    bgView.frame.size.height = textFieldHeight

    drawErrorText(rect)
  }

  private func invalidateErrorTextContentSize() {
    guard let text = errorText else { return }

    let bounds = measureText(text, attributes: [NSFontAttributeName: errorFont])
    errorTextHeight = bounds.height
    invalidateIntrinsicContentSize()
  }

  private func drawErrorText(rect: CGRect) {
    guard let text = errorText else { return }

    let errorTextBounds = CGRect(x: bgView.frame.origin.x,
                                 y: bgView.frame.height + errorTextPadding,
                                 width: bgView.frame.width,
                                 height: errorTextHeight)

    text.drawInRect(errorTextBounds,
                    withAttributes: [
                      NSFontAttributeName: errorFont,
                      NSForegroundColorAttributeName: errorTextColor
                    ])
  }

  private func offsetRectForEditing(rect: CGRect) -> CGRect {
    return UIEdgeInsetsInsetRect(rect, UIEdgeInsets(top: 0, left: 5, bottom: errorTextHeight, right: 5))
  }

  private func offsetRectForEdgeView(rect: CGRect) -> CGRect {
    let x = CGFloat(5)
    let y = (bgView.frame.height/2) - (rect.height/2)
    return CGRect(x: x, y: y, width: rect.width, height: rect.height)
  }

  private func setupBackgroundView() {
    bgView.layer.cornerRadius = 5
    bgView.layer.borderWidth = 1
    bgView.layer.borderColor = UIColor.blackColor().colorWithAlphaComponent(0.1).CGColor
    bgView.backgroundColor = UIColor.clearColor()
    bgView.userInteractionEnabled = false // Let touch events fall through
    addSubview(bgView)
  }

  private func measureText(text: String, attributes: [String:AnyObject]) -> CGRect {
    let nsString = NSString(string: text)
    return nsString.boundingRectWithSize(self.frame.size,
                                  options: .UsesLineFragmentOrigin,
                                  attributes: attributes,
                                  context: nil)
  }

  private func calculateHeight() -> CGFloat {
    return errorTextHeight + textFieldHeight + errorTextPadding
  }
}

以上是关于swift 具有错误文本支持的UITextField。在UITextField下面绘制错误文本。的主要内容,如果未能解决你的问题,请参考以下文章

swift UITextFieldDelegate 扩展

具有多个文本字段输入视图的多个选取器视图 Swift

iOS Swift - 文本到语音使应用程序崩溃

创建类、结构或新的 swift 文件以创建具有特定样式的可重用文本框?

Swift-错误处理(Error Handling)(十六)

Swift 开源markdown 笔记应用,支持Mac/iOS