某莔の异次元空间
针对某个 UITextField 禁用第三方键盘
更新于:3 个月前 标签:iOSSwiftUITextField

前两天在开发iOS程序的验证码输入框时遇到了一个问题,当我给UITextField实例对象更改 keyboardType 属性为 .numberPad 时,如果系统正在使用第三方输入法,则不能强行调用系统数字键盘。搜索发现要禁用第三方键盘需要在AppDelegate中实现:

func application(_ application: UIApplication, shouldAllowExtensionPointIdentifier extensionPointIdentifier: UIApplication.ExtensionPointIdentifier) -> Bool {
    return false
}

可如此一来就全局禁用了第三方键盘,不是我想要的结果。本文介绍一种针对某个UITextField实现禁用第三方键盘的方案。

1、添加属性

UITextField类添加extension,包含一条静态变量和一条「存储属性」。Swift不允许在extension中直接增加「存储属性」,但是在我们的实际开发中可以借助关联对象,实现类似增加存储属性的效果,如下所示。

extension UITextField {
    private struct AssociatedKey {
        static var identifier: String = "identifier"
    }
    var usingSystemKeyboard: Bool {
        get {
            return (objc_getAssociatedObject(self, &AssociatedKey.identifier) as? Bool) ?? false
        }
        set {
            objc_setAssociatedObject(self, &AssociatedKey.identifier, newValue, .OBJC_ASSOCIATION_ASSIGN)
        }
    }
    static var globalUsingSystemKeyboard = false
}

2、创建子类

创建 UITextField 的子类,以 ACTextField 为例,初始化时 NotificationCenter 监听即将输入和即将结束输入的状态,在方法里更改 globalUsingSystemKeyboard 变量,关键代码如下。

class ACTextField: UITextField {
    deinit {
        NotificationCenter.default.removeObserver(self)
    }
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        NotificationCenter.default.addObserver(self, selector: #selector(self.textDidBeginEdit(_:)), name: UITextField.textDidBeginEditingNotification, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(self.textDidEndEdit(_:)), name: UITextField.textDidEndEditingNotification, object: nil)
    }
    @objc func textDidBeginEdit(_ notification: Notification) {
        UITextField.globalUsingSystemKeyboard = self.usingSystemKeyboard
    }
    @objc func textDidEndEdit(_ notification: Notification) {
        UITextField.globalUsingSystemKeyboard = false
    }
}

3、配置

AppDelegate中修改:

func application(_ application: UIApplication, shouldAllowExtensionPointIdentifier extensionPointIdentifier: UIApplication.ExtensionPointIdentifier) -> Bool {
    if UITextField.globalUsingSystemKeyboard {
        return false
    }
    return true
}

4、使用

ACTextField 的实例对象指定 usingSystemKeyboard 属性。

let acTextField = ACTextField(frame: frame)
acTextField.usingSystemKeyboard = true

即可实现针对某个 UITextField 禁用第三方键盘。

点评一下
Powered By AraComment
快来抢沙发吧~
次元物语

载入中..

-「载入中..」

• 按部就班填坑

• 天道轮回 斗转星移

• Alive: 0 天 0 小时 0 分

• © 2018-2022 Arabaku

Support:

frame ssr server DNS
back2top