在UITextfield

时间:2016-01-21 00:46:29

标签: objective-c uikit tvos apple-tv

我有一个简单的视图,它有两个textview和一个按钮。所有控件都垂直放置。我可以使用遥控器从一个控件导航到另一个控件。但是,我试图让以下方案有效:

  1. 用户启动应用程序(焦点位于第一个文本字段)
  2. 用户输入文本字段并使用全屏键盘,然后她点击"下一步"按钮
  3. 该应用程序显示第二个文本字段(全屏键盘),在某些文本中键入并点击"完成"按钮
  4. 应用程序离开全屏键盘并对焦按钮
  5. 虽然步骤1-3开箱即用,但以编程方式更改焦点(4)并不起作用。这是一些代码:

    - (BOOL)textFieldShouldReturn:(UITextField *)textField {
        if(textField == self.textfieldB) {
            self.activeView = self.textfieldB;
            [self setNeedsFocusUpdate];
            [self updateFocusIfNeeded];
            return YES;
        } 
        return NO;
    }
    

    并在- (UIView *)preferredFocusedView中我返回存储在self.activeView中的任何内容(是的,它将返回按钮实例)。所有方法都按预期调用,但焦点不会改变。我在这里做错了什么?

    提前致谢!

4 个答案:

答案 0 :(得分:3)

根据this developer forums thread,行为是有意的:

  

当解除显示的视图控制器(如全屏键盘)时,UIKit会自动将焦点返回到首次显示该视图控制器时的位置,如果该视图仍然可以调焦。这样焦点会自动返回到用户期望的位置。目前没有覆盖此行为的机制。

在类似情况下,我从键盘屏幕返回后延迟切换焦点。这是一个丑陋的黑客,我希望UIKit对此并不那么自以为是。

答案 1 :(得分:0)

如果包含的UIViewController的restoresFocusAfterTransition设置为false,则可以更改

只需设置restoresFocusAfterTransition = false,然后覆盖preferredFocusEnvironments

答案 2 :(得分:0)

是的,您可以通过执行以下步骤来完成第4步:

    @IBOutlet weak var loginButton: UIButton!
    var focusedView: UIView?

    override var preferredFocusedView: UIView? {
        return focusedView
    }

    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        if textField == passwordTextField {
            focusedView = loginButton
        }
        return true
    }

答案 3 :(得分:0)

因此,我遇到的所有建议都对我没有真正的帮助,包括将新的restoresFocusAfterTransition设置为false。

除此之外,唯一有效的方法是基于6rchid的答案,并延迟了对焦点引擎更新的考虑。

class EmailViewController: UIViewController {

    @IBOutlet weak var emailTextField: UITextField!
    @IBOutlet weak var submitButton: UIButton!

    private var focusedEnvironments: [UIFocusEnvironment] = [UIFocusEnvironment]()

    override var preferredFocusEnvironments: [UIFocusEnvironment] {
        return focusedEnvironments
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        restoresFocusAfterTransition = false

        focusedEnvironments = [emailTextField, submitButton]
    }

}

extension EmailViewController: UITextFieldDelegate {

    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {

        emailTextField.isEnabled = false
        focusedEnvironments = [submitEmailButton]

        submitButton.setNeedsFocusUpdate()

        UIView.transition(with: submitEmailButton, duration: 1.0, options: .transitionCrossDissolve, animations: {
            self.submitButton.isEnabled = true
        }) { (_) in
            // re-enable this once focus updates have completed
            self.emailTextField.isEnabled = true
        }
        return true
    }
}

如果焦点更新完成前UITextField处于启用状态,则焦点似乎总是想重置为UITextField。因此,诀窍是先禁用它,然后在需要时重新启用它。