【问题标题】:Grey out return key programmatically以编程方式灰显返回键
【发布时间】:2015-08-06 04:11:14
【问题描述】:

当(且仅当)用户输入有效的电子邮件地址时,我希望启用UITextField 键盘的返回键。

我试过a solution that dates back from 2009,它使用私有方法setReturnKeyEnabled。不幸的是,这种方法似乎不再存在:

选择器“setReturnKeyEnabled:”没有已知的实例方法

如何以编程方式启用和禁用键盘的返回键?

【问题讨论】:

  • 如果您希望返回键变灰,您应该在问题中这样说。因为“禁用”可能意味着很多事情。我可以争辩说,如果返回键不起作用,它也会被禁用。而且似乎不可能将返回键变灰,至少不能使用有记录的技术。
  • 我已经编辑了标题,谢谢。

标签: ios ios8 uitextfield uikeyboard ios8.3


【解决方案1】:

您并没有真正启用禁用返回键。相反,如果用户按下返回键,则调用委托方法 -textFieldShouldReturn:。如果你想在这种情况下隐藏键盘,你必须在你的委托方法中的文本字段上调用-resignFirstResponder

https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITextFieldDelegate_Protocol/index.html

【讨论】:

  • 我希望返回键变灰。这不适用于textFieldShouldReturn
  • 我从未在 UIKeyboard 上看到灰色的返回键
  • 文本字段为空时查看enablesReturnKeyAutomatically = NO
【解决方案2】:
  1. 在您的 UITextField 上设置委托
  2. 对于您的委托实例(您刚刚设置的符合 UITextFieldDelegate 的实例),实现:- (BOOL)textFieldShouldReturn:(UITextField *)textField

如果您试图保持 textField 始终“正确”并且不允许用户在 textfield 变为对您首选的格式/验证有误。绝对值得查看 UITextFieldDelegate 的文档,了解所有可能的回调。

【讨论】:

  • 啊,路过的投反对票——想说明你的问题,反对票?
【解决方案3】:

所有其他解决方案都不能回答这个问题。 OP 希望将键盘上的返回按钮“变灰”,作为给用户的视觉信号。

这是我的解决方案,适用于 iOS 13。您可能需要针对其他 iOS 版本稍微修改解决方案。

首先,我扩展UITextFieldDelegate

func getKeyboard() -> UIView?
    {
        for window in UIApplication.shared.windows.reversed()
        {
            if window.debugDescription.contains("UIRemoteKeyboardWindow") {
                if let inputView = window.subviews
                    .first? // UIInputSetContainerView
                    .subviews
                    .first // UIInputSetHostView
                {
                    for view in inputView.subviews {
                        if view.debugDescription.contains("_UIKBCompatInputView"), let keyboard = view.subviews.first, keyboard.debugDescription.contains( "UIKeyboardAutomatic") {
                            return keyboard
                        }
                    }
                }
                
            }
        }
        return nil
    }

然后,当我需要禁用“return”键时,我们可以这样做(将delegate替换为您的委托对象的变量名):

if let keyboard = delegate.getKeyboard(){
    keyboard.setValue(text == nil, forKey: "returnKeyEnabled")
}

【讨论】:

    【解决方案4】:

    扩展UITextFieldDelegate

    extension UITextFieldDelegate {
        func setReturnKeyState(for textField: UITextField, isEnabled: Bool, delay: Double? = nil) {
            textField.enablesReturnKeyAutomatically = false
            if textField.delegate != nil {
                if let delay = delay {
                    DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
                        textField.setValue(isEnabled, forKeyPath: "inputDelegate.returnKeyEnabled")
                    }
                } else {
                    textField.setValue(isEnabled, forKeyPath: "inputDelegate.returnKeyEnabled")
                }
            }
        }
    }
    

    定义验证规则。

    private func isValidEmail(_ input: String?) -> Bool {
        guard let input = input else { return false }
        let emailRegex = try! NSRegularExpression(pattern: ".+@.+\\..+")
        let fullNSRange = NSRange(input.startIndex..., in: input)
        return emailRegex.rangeOfFirstMatch(in: input, options: .anchored, range: fullNSRange) == fullNSRange
    }
    

    UITextFieldDelegate 的方法中使用setReturnKeyState(for textField: ...)

    func textFieldDidBeginEditing(_ textField: UITextField) {
        setReturnKeyState(for: textField, isEnabled: isValidEmail(textField.text), delay: 0.1) // A bit hacky it needs delay here
    }
    
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        if var text = textField.text, let range = Range(range, in: text) {
            text.replaceSubrange(range, with: string)
            setReturnKeyState(for: textField, isEnabled: isValidEmail(text))
        }
        return true
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-12
      • 1970-01-01
      • 1970-01-01
      • 2020-09-30
      • 2012-04-04
      • 2023-03-31
      相关资源
      最近更新 更多