简要地说:我有ViewController两个UITextField要素。当loginField为firstResponder时,之后
ViewController
UITextField
self.passwordField.becomeFirstResponder()
登录字段中的文本跳到左上角并返回。更奇怪的是:此故障仅在第一时间重现,然后您需要重新创建ViewController以观察此行为
这是故障的视频http://tinypic.com/player.php?v=6nsemw%3E&s=8#.VgVb3cuqpHx
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,为此我将底部空间更改为超级视图,因此即使显示键盘,用户也可以滚动所有内容
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有一些垃圾帧值,这是使用next按钮更改第一响应者时的日志(工作正常,没有故障):
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] -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]
这是我点击第二个textField时的日志:
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
我发现我还有另一个键盘控制器,可以接收键盘通知并制作一些动画。那就是问题所在
根据您编辑的问题,当您点击键盘上的下一个按钮时,我会看到以下内容:
resignFirstResponder()
becomeFirstResponder()
keyboardWillHide
keyboardWillShow
self.view.layoutIfNeeded()
因此,文本字段的布局是“固定的”,并且当您在keyboardWillShow文本字段中的文本中进行动画处理时,它不再“跳转”了,因为您在中进行了布局keyboardWillHide。
但是,当您仅点击另一个文本字段时,仅会keyboardWillShow被调用,布局不会在文本字段中“固定”,并且在为视图设置动画时,文本会产生“跳转”动画。
这就是为什么当您单击键盘上的“下一步”时,它不会跳转,而当您单击另一个文本字段时,它会跳转。
所以我建议将其更改为:
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) } }) } }