【问题标题】:UITextField losing firstResponder after view appears视图出现后 UITextField 丢失 firstResponder
【发布时间】:2014-01-09 21:57:12
【问题描述】:

我有一个UIPageViewController。一页有一个按钮,另一页有一个带有按钮的UITextField。当页面滚动到带有字段的视图时,我希望它到becomeFirstResponder 并打开键盘。以下是发生的事情:

  • 我调用[self.locationQuery becomeFirstResponder] ViewController 的viewDidAppear 方法。但它永远不会打开键盘。

  • 我在viewWillAppear 中也这样做了,它会短暂出现,但很快就会消失。

  • 如果我在带有文本字段的页面上,然后将页面拉到一半然后放开(不更改页面),self.locationQuery 就可以很好地获得焦点。

似乎有其他东西正在从该字段中获取 firstResponder 状态,但我完全不知道是什么,以及为什么它只会在页面更改时发生(而不是在翻页失败后显示)。有什么想法吗?

更新

我创建了一种爬取视图的方法,以查看是否有任何其他视图确实采用了 firstResponder(来自此问题的答案:Get the current first responder without using a private API)。结果:

  • 当我明确地为文本字段提供第一响应者时,该方法报告它具有第一响应者状态。

  • 如果我不这样做,它会返回null

现在我更加困惑了。

【问题讨论】:

    标签: objective-c uipageviewcontroller first-responder


    【解决方案1】:

    我并不真正了解导致我的问题的本质,但我能够通过将调用包装在 viewDidAppear 中的异步调度中来解决它:

    dispatch_async(dispatch_get_main_queue(), ^{
        MapManualViewController *strongSelf = weakSelf;
        [strongSelf.locationQuery becomeFirstResponder];
    });
    

    【讨论】:

    • 遇到了同样的问题,已经解决了,谢谢。我也不完全理解它,但我想因为我们通过键盘出现来触摸 UI,所以获取主队列是有意义的
    • 我尝试在由 UIKeyboardWillHideNotification 触发的方法上设置断点并查看堆栈跟踪。看起来这是由 UIPageViewController 的实现细节引起的,它在动画结束时在两个内部滚动视图之间交换视图控制器的视图。然后 UITextView 将退出第一响应者,因为它已从视图层次结构中短暂移除。看起来您的解决方案只是延迟成为第一响应者,直到下一个运行循环。
    【解决方案2】:

    这个人从我的生活中偷走了几个小时。这是 Swift 3.x 的实现。

    DispatchQueue.main.async(execute: {() -> Void in
        let strongSelf: MapManualViewController = self
        strongSelf. textField.becomeFirstResponder()
    })
    

    我也放到viewDidAppear

    【讨论】:

    • 这里不需要strongSelf,可以简写为DispatchQueue.main.async() { self.textField.becomeFirstResoonder() }
    猜你喜欢
    • 1970-01-01
    • 2012-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-21
    • 2010-12-19
    相关资源
    最近更新 更多