
合理的设计都千篇一律,奇葩的需求各有各的不同。
我们在使用
UITextField或者UITextView的时候,如果将键盘回车键ReturnKey当做UIButton,通常,会使用enablesReturnKeyAutomatically 属性来控制其isEnabled 。
现有账号密码登录界面,场景如下:
if mobileTextField.hasText && passwordTextField.text?.count ?? 0 >= 6 {
submitButton.isEnabled = true
returnKey.isEnabled = true
} else {
submitButton.isEnabled = false
returnKey.isEnabled = false
}
开发者无法通过API 直接访问键盘的ReturnKey (而且找不到私有)。API
首先关注enablesReturnKeyAutomatically 属性:
/**
default is NO
(when YES, will automatically disable return key
when text widget has zero-length contents,
and will automatically enable
when text widget has non-zero-length contents)
*/
optional var enablesReturnKeyAutomatically: Bool { get set }
通过文档我们可以看到,当enablesReturnKeyAutomatically = true 的时候,UITextField或者UITextView 会根据其text 长度来控制键盘ReturnKey 的可用状态。
考虑到,我们可以使用UIKeyInput 协议中的deleteBackward() 方法来监控键盘的删除键,那么我们是否可以实现var hasText: Bool { get } 来控制键盘ReturnKey呢?
/// UIKeyInput协议内容
public protocol UIKeyInput : UITextInputTraits {
var hasText: Bool { get }
func insertText(_ text: String)
func deleteBackward()
}
答案是肯定的!
我们实现一个UITextField 的子类ManuallyTextField ,并使其有一个名为ReturnKeyDelegate的协议:
protocol ReturnKeyDelegate: NSObjectProtocol {
func textFieldShouldEnableReturnKey(_ textField: UITextField) -> Bool
}
class ManuallyTextField: UITextField {
weak var returnKeyDelegate: ReturnKeyDelegate?
override var hasText: Bool {
if let enable = self.returnKeyDelegate?.textFieldShouldEnableReturnKey(self) {
return enable
}
return super.hasText
}
}
在textFieldShouldEnableReturnKey(_ textField: UITextField) -> Bool 协议方法中,实现控制代码:
passwordTextField.returnKeyDelegate = self
func textFieldShouldEnableReturnKey(_ textField: UITextField) -> Bool {
if !self.mobileTextField.hasText {
return false
}
return textField.text?.count ?? 0 >= 6
}
