我有一个简单的视图,它有两个textview和一个按钮。所有控件都垂直放置。我可以使用遥控器从一个控件导航到另一个控件。但是,我试图让以下方案有效:
虽然步骤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中的任何内容(是的,它将返回按钮实例)。所有方法都按预期调用,但焦点不会改变。我在这里做错了什么?
提前致谢!
答案 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
。因此,诀窍是先禁用它,然后在需要时重新启用它。