UITextField文本跳转iOS 9 [英] UITextField text jumps iOS 9
问题描述
上一个问题的链接:
UITextField文字跳转
简要说明:
我有 ViewController
,带有2 UITextField
元素。当loginField为firstResponder时,
Briefly:
I have ViewController
with 2 UITextField
elements. When loginField is firstResponder, after
self.passwordField.becomeFirstResponder()
登录字段中的文本跳转到左上角和后面。而且更奇怪的是:这个故障只是第一次重现,然后你需要重新创建 ViewController
来观察这种行为
text in login field jumps to the top left corner and back. And what's more strange: this glitch reproduces only first time, then you need recreate ViewController
to observe this behavior
这里是一个小故障的视频 http://tinypic.com/ player.php?v = 6nsemw%3E& s = 8#.VgVb3cuqpHx
Here is video of the glitch 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
}
是否有人被困这个bug?有什么建议吗?
Is there anybody who has been stucked with this bug? Any suggestions?
我的主视图是UIScrollView,为此我将底部空间更改为superview ,因此即使键盘显示,用户也可以滚动所有内容
My main view is UIScrollView, for which I change bottom space to superview, so user can scroll all the content even when keyboard is shown
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有一些垃圾框架值,这里是使用下一个按钮更改第一响应者时的日志(工作正常,没有毛刺):
As I discovered keyboard notifications in iOS7, 8 and 9 very differ. So, in iOS 9 notifications are sent while changing firstResponder even if keyboard will not Show/Hide. Also, when I change firstResponder with tapping on textField (not tapping Next on keyboard which is handled by my code), there is only KeyboardWillShow notification and no KeyboardWillHide. And as for me, userInfo has some trash frame values, here is log when changing first responder using next button (works ok, without glitches):
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: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]
当我点击第二个textField时,这是日志:
And here is log when I tap on the second 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]
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]
< h1>分辨率
我发现我有另一个接收键盘通知的键盘控制器tions并制作一些动画。这就是问题所在
Resolution
I discovered that I have another Keyboard Controller that receives keyboard notifications and make some animations. That's where the problem lies
推荐答案
根据您编辑的问题,当您点击键盘上的下一个按钮时,我可以看到这一点:
Based on your edited question I can see this, when you tap next button on keyboard:
- 您正在调用
resignFirstResponder()
然后yesFirstResponder( )
。这会调用keyboardWillHide
通知,然后keyboardWillShow
通知 - 在
keyboardWillHide
你有self.view.layoutIfNeeded()
,它可以在没有动画的情况下布局视图(和子视图 - 文本字段)。
- You're calling
resignFirstResponder()
and thenbecomeFirstResponder()
. This callskeyboardWillHide
notification and thenkeyboardWillShow
notification - In
keyboardWillHide
you haveself.view.layoutIfNeeded()
which layouts the view (and subviews - textfields) without animation.
因此,文本字段布局是固定的,当您在中执行动画时,keyboardWillShow
textfield中的文本不再跳,因为你在 keyboardWillHide
中做了布局。
Because of this the textfield layout is "fixed" and when you do animation in keyboardWillShow
the text in textfield doesn't "jump" anymore, because you did layout in keyboardWillHide
.
但是当你点击另一个文本字段时,只调用 keyboardWillShow
,布局在文本字段中没有修复当您为视图设置动画时,文本会执行跳转动画。
But when you just tap another textfield, only keyboardWillShow
is called, layout is not "fixed" in textfield and when you animate the view, the text does a "jump" animation.
这就是为什么当您点击键盘上的下一个键时它不会跳转但是当您刚刚跳转时它会跳转点击另一个文本字段。
That's why it doesn't jump when you tap next on keyboard but it does jump when you just tap another textfield.
所以我建议将其更改为:
So I would advise to change it to this:
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)
}
})
}
}
这篇关于UITextField文本跳转iOS 9的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!