上一个问题的链接: UITextField text jumps
简要说明:
我有 ViewController
和 2 个 UITextField
元素。当 loginField 为 firstResponder 时,
self.passwordField.becomeFirstResponder()
登录字段中的文本跳转到左上角并返回。更奇怪的是:这个故障只在第一次出现,然后你需要重新创建 ViewController
来观察这个行为
这是故障视频 http://tinypic.com/player.php?v=6nsemw%3E&s=8#.VgVb3cuqpHx
我最终得到了这个(不适用于 iOS 9):
func textFieldShouldReturn(textField: UITextField) -> Bool {
if textField === self.loginField {
self.loginField.resignFirstResponder()
// Shitty workaround. Hi, Apple!
self.loginField.setNeedsLayout()
self.loginField.layoutIfNeeded()
self.passwordField.becomeFirstResponder()
return false
}
return true
}
有人被这个错误困住了吗?有什么建议吗?
键盘通知处理程序
我的主视图是 UIScrollView,为此我将底部空间更改为 super View ,因此即使显示键盘,用户也可以滚动所有内容
func keyboardWillShow(notification : NSNotification) {
let keyboardInfo = notification.userInfo!
let keyboardFrame = keyboardInfo[UIKeyboardFrameEndUserInfoKey]!.CGRectValue
let animDuration = keyboardInfo[UIKeyboardAnimationDurationUserInfoKey]!.doubleValue!
UIView.animateWithDuration(animDuration, animations: {
self.scrollViewBottom.constant = keyboardFrame.height
self.view.layoutIfNeeded()
let offsetY = CGRectGetMaxY(self.loginButton.frame) + 10 - self.scrollView.frame.height
if offsetY > 0 {
self.scrollView.contentOffset = CGPointMake(0, offsetY)
}
})
}
func keyboardWillHide(notification : NSNotification) {
self.scrollViewBottom.constant = 0
self.view.layoutIfNeeded()
}
我发现 iOS7、8 和 9 中的键盘通知非常不同。因此,在 iOS 9 中,即使键盘不会显示/隐藏,也会在更改 firstResponder 时发送通知。此外,当我通过点击 textField 更改 firstResponder(而不是点击由我的代码处理的键盘上的 Next)时,只有 KeyboardWillShow 通知而没有 KeyboardWillHide。至于我,userInfo 有一些垃圾帧值,这是使用下一步按钮更改第一响应者时的日志(工作正常,没有故障):
2015-10-07 12:54:13.870 keyboardWillHide: [UIKeyboardFrameBeginUserInfoKey: NSRect: {{0, 352}, {320, 216}}, UIKeyboardCenterBeginUserInfoKey: NSPoint: {160, 460}, UIKeyboardFrameEndUserInfoKey: NSRect: {{0, 568}, {320, 216}}, UIKeyboardCenterEndUserInfoKey: NSPoint: {160, 676}, UIKeyboardAnimationDurationUserInfoKey: 0.25, UIKeyboardIsLocalUserInfoKey: 1, UIKeyboardBoundsUserInfoKey: NSRect: {{0, 0}, {320, 216}}, UIKeyboardAnimationCurveUserInfoKey: 7] 2015-10-07 12:54:13.896 keyboardWillShow: [UIKeyboardFrameBeginUserInfoKey: NSRect: {{0, 352}, {320, 216}}, UIKeyboardCenterBeginUserInfoKey: NSPoint: {160, 460}, UIKeyboardFrameEndUserInfoKey: NSRect: {{0, 352}, {320, 216}}, UIKeyboardCenterEndUserInfoKey: NSPoint: {160, 460}, UIKeyboardAnimationDurationUserInfoKey: 0.25, UIKeyboardIsLocalUserInfoKey: 1, UIKeyboardBoundsUserInfoKey: NSRect: {{0, 0}, {320, 216}}, UIKeyboardAnimationCurveUserInfoKey: 7]
这是我点击第二个文本字段时的日志:
2015-10-07 12:55:13.879 keyboardWillShow:[UIKeyboardFrameBeginUserInfoKey: NSRect: {{0, 352}, {320, 216}}, UIKeyboardCenterBeginUserInfoKey: NSPoint: {160, 460}, UIKeyboardFrameEndUserInfoKey: NSRect: {{0, 352}, {320, 216}}, UIKeyboardCenterEndUserInfoKey: NSPoint: {160, 460},
UIKeyboardAnimationDurationUserInfoKey: 0.25, UIKeyboardIsLocalUserInfoKey: 1, UIKeyboardBoundsUserInfoKey: NSRect: {{0, 0}, {320, 216}}, UIKeyboardAnimationCurveUserInfoKey: 7]
决议
我发现我有另一个键盘 Controller 可以接收键盘通知并制作一些动画。这就是问题所在
最佳答案
根据您编辑的问题,当您点击键盘上的下一步按钮时,我可以看到:
- 您正在调用
resignFirstResponder()
,然后调用becomeFirstResponder()
。这会调用keyboardWillHide
通知,然后调用keyboardWillShow
通知 - 在
keyboardWillHide
中,您有self.view.layoutIfNeeded()
布局没有动画的 View (和 subview - 文本字段)。
因此,文本字段布局是“固定的”,当您在 keyboardWillShow
中执行动画时,文本字段中的文本不再“跳跃”,因为您在 keyboardWillHide中进行了布局
。
但是当您点击另一个文本框时,只有 keyboardWillShow
被调用,文本框的布局不是“固定”的,当您为 View 设置动画时,文本会执行“跳跃”动画。
这就是为什么当您在键盘上点击下一步时它不会跳转,但当您点击另一个文本字段时它会跳转。
所以我建议将其更改为:
func textFieldShouldReturn(textField: UITextField) -> Bool {
if textField === self.loginField {
self.passwordField.becomeFirstResponder()
return false
}
return true
}
func keyboardWillShow(notification : NSNotification) {
let keyboardInfo = notification.userInfo!
let keyboardFrame = keyboardInfo[UIKeyboardFrameEndUserInfoKey]!.CGRectValue
let animDuration = keyboardInfo[UIKeyboardAnimationDurationUserInfoKey]!.doubleValue!
self.loginField.layoutIfNeeded()
self.passwordField.layoutIfNeeded()
if keyboardFrame.height != self.scrollViewBottom.constant {
UIView.animateWithDuration(animDuration, animations: {
self.scrollViewBottom.constant = keyboardFrame.height
self.view.layoutIfNeeded()
let offsetY = CGRectGetMaxY(self.loginButton.frame) + 10 - self.scrollView.frame.height
if offsetY > 0 {
self.scrollView.contentOffset = CGPointMake(0, offsetY)
}
})
}
}
关于ios - UITextField 文本跳转 iOS 9,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32987046/