ios - UITextField 文本跳转 iOS 9

标签 ios iphone swift swift2 ios9

上一个问题的链接: 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 可以接收键盘通知并制作一些动画。这就是问题所在

最佳答案

根据您编辑的问题,当您点击键盘上的下一步按钮时,我可以看到:

  1. 您正在调用 resignFirstResponder(),然后调用 becomeFirstResponder()。这会调用 keyboardWillHide 通知,然后调用 keyboardWillShow 通知
  2. 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/

相关文章:

iphone - 通过 NSTimer UserInfo 传递数据

Swift:for循环等待响应并根据响应返回值

objective-c - iOS 的国家和国家拨号代码列表

ios - 有时在 Xcode (Swift) 中,应用程序会因滑动删除操作而崩溃

iphone - UIManagedDocument 和 NSFetchedResultsController

iphone - 将其添加到项目时无法将任何新的 .H 文件添加到目标,

iOS Swift 3 - 如何保存可以拉到任何 View Controller 的数据

ios - 从 Swift 2.3 -> 3.2 转换时,无法将 String 类型的值转换为指定类型 NSManagedObjectContext

objective-c - XCode IBOutlet UIView 添加到 ViewControllers .h - 无法识别 UIViews 类型

iOS 9 : “unexpected use of reserved word ‘let’ in strict mode” + “Can’ t find variable: fetch”. 转译问题?怎么修?