上一个问题的链接: UITextField text jumps
简言之:
我有ViewController
个UITextField
个元素。当loginField是firstResponder时,在
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,为此我将底部空间更改为superview,因此即使显示键盘,用户也可以滚动所有内容
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]
当我点击第二个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]
我发现我有另一个键盘控制器,它接收键盘通知并制作一些动画。这就是问题所在
答案 0 :(得分:7)
根据您编辑的问题,当您点击键盘上的下一个按钮时,我可以看到这一点:
resignFirstResponder()
,然后呼叫becomeFirstResponder()
。这会调用keyboardWillHide
通知,然后调用keyboardWillShow
通知keyboardWillHide
中,您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)
}
})
}
}
答案 1 :(得分:6)
Tnx到haluzak:
$wheelnumber = $_POST['wheelnumber'];
答案 2 :(得分:5)
当我试图改变第一响应者时,我遇到了同样的问题。这个问题有一个更好的解决方案。只需实现UITextField子类并在地方使用,您可以在其中设置文本字段的动画(键盘,首先响应切换等)。
@interface UITextFieldFixed : UITextField
@end
@implementation UITextFieldFixed
- (BOOL)resignFirstResponder
{
BOOL result = [super resignFirstResponder];
[self setNeedsLayout];
[self layoutIfNeeded];
return result;
}
@end
有关问题的详细信息:https://github.com/foundry/UITextFieldBug
复制并粘贴Swift3 ...
class UITextFieldFixed: UITextField {
override func resignFirstResponder() -> Bool {
let r = super.resignFirstResponder()
self.setNeedsLayout()
self.layoutIfNeeded()
return r
}
}
答案 3 :(得分:0)
将此代码放入键盘将显示通知,然后再进行任何动画:
UIView.performWithoutAnimation({
self.yourTextField1.layoutIfNeeded()
self.yourTextField2.layoutIfNeeded()
//etc.
})
答案 4 :(得分:0)
以下是您需要编写的用于停止跳转文本的简单代码。这对我有用。
func textFieldDidEndEditing(_ textField: UITextField) {
// Workaround for the jumping text bug.
textField.resignFirstResponder()
textField.layoutIfNeeded()
}