自定義UITextField,支持placeholderFont、placeholderColor、offset、isEnableDecimalLimit
- 使用方法
lazy var textField = TextField()
view.addSubview(textField)
textField.frame = CGRect(x: 0, y: 0, width: 400, height: 60)
textField.center = view.center
textField.placeholder = "請輸入內容..."
textField.placeholderFont = .systemFont(ofSize: 20)
textField.placeholderColor = .red
textField.isEnableDecimalLimit = true
textField.offset = CGPoint(x: 10, y: 10)
textField.font = .systemFont(ofSize: 30)
textField.backgroundColor = .lightGray
textField.keyboardType = .decimalPad
- 源碼分享
class TextField: UITextField {
/// 占位字體
var placeholderFont: UIFont? {
willSet {
if let label = value(forKey: "placeholderLabel") as? UILabel {
label.font = newValue
}
}
}
/// 占位顏色
var placeholderColor: UIColor? {
willSet {
if let label = value(forKey: "placeholderLabel") as? UILabel {
label.textColor = newValue
}
}
}
/// 內邊距偏移量
var offset: CGPoint = .zero
/// 是否啟用小數(shù)點后僅允許兩位的輸入限制
var isEnableDecimalLimit: Bool = false
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override init(frame: CGRect) {
super.init(frame: frame)
delegate = self
}
}
extension TextField {
/// 占位符偏移量
override func placeholderRect(forBounds bounds: CGRect) -> CGRect {
if let leftView {
return CGRectOffset(CGRect(origin: bounds.origin, size: CGSize(width: bounds.width - leftView.bounds.width - offset.x, height: bounds.height)), leftView.bounds.width + offset.x, offset.y)
}
return CGRectOffset(CGRect(origin: bounds.origin, size: CGSize(width: bounds.width - offset.x, height: bounds.height)), offset.x, offset.y)
}
/// 文本最終顯示偏移量
override func textRect(forBounds bounds: CGRect) -> CGRect {
if let leftView {
return CGRectOffset(CGRect(origin: bounds.origin, size: CGSize(width: bounds.width - leftView.bounds.width - offset.x, height: bounds.height)), leftView.bounds.width + offset.x, offset.y)
}
return CGRectOffset(CGRect(origin: bounds.origin, size: CGSize(width: bounds.width - offset.x, height: bounds.height)), offset.x, offset.y)
}
/// 文本編輯時偏移量
override func editingRect(forBounds bounds: CGRect) -> CGRect {
if let leftView {
return CGRectOffset(CGRect(origin: bounds.origin, size: CGSize(width: bounds.width - leftView.bounds.width - offset.x, height: bounds.height)), leftView.bounds.width + offset.x, offset.y)
}
return CGRectOffset(CGRect(origin: bounds.origin, size: CGSize(width: bounds.width - offset.x, height: bounds.height)), offset.x, offset.y)
}
}
extension TextField: UITextFieldDelegate {
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
guard isEnableDecimalLimit else { return true }
// 獲取當前文本
let currentText = (textField.text as NSString?)?.replacingCharacters(in: range, with: string) ?? ""
// 正則表達式
let regex = "^$|^0$|^0\\.[0-9]{0,2}$|^[1-9][0-9]*\\.?[0-9]{0,2}$"
// 創(chuàng)建正則表達式對象
let expression = try? NSRegularExpression(pattern: regex, options: [])
// 校驗當前文本是否符合正則表達式
if let _ = expression?.firstMatch(in: currentText, options: [], range: NSRange(location: 0, length: currentText.utf16.count)) {
return true
}
// 若不符合正則表達式,則不允許更改
return false
}
}