Setting becomeFirstResponder on viewController nested in PageViewController

你离开我真会死。 提交于 2020-06-28 06:22:15

问题


I have a pageViewController that has two child view controllers that you can swipe between. One of them has a textView that I want to be the first responder when you scroll onto that page, then lose focus when you scroll away. Right now I have this:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    composeTextView.delegate = self
    composeTextView.becomeFirstResponder()
}

The keyboard shows up as soon as you start to scroll onto the view. But as soon as the scrolling finishes, the keyboard disappears.

Any ideas why this is happening?


回答1:


It works ok transition style Page Curl but not with Scroll.

I think the problem is immediately after viewDidAppear the old page resigns first responder and a new one is chosen thus whatever you set as firstResponder is lost. This is caused by the old and new view being repeatedly added and removed from the window which affects the responder chain. I think that after the old view scrolls off screen it is added back to the window for some reason because when you scroll back to it, it's ready to go.

As you can see in this log, after viewDidAppear there are many odd changes to both view's window. The new view is 0x7fd87fa24160 so why is the old view 0x7fd87fa059a0 being removed and added to the window multiple times?

2020-06-01 10:22:14.093911+0100 Paging2[45575:3540067] DetailViewController 0x7fd87fa15850 viewDidAppear: 0x7fd87fa24160
2020-06-01 10:22:14.094973+0100 Paging2[45575:3540067] MyView 0x7fd87fa059a0 didMoveToWindow 0x0
2020-06-01 10:22:14.095358+0100 Paging2[45575:3540067] MyView 0x7fd87fa24160 didMoveToWindow 0x0
2020-06-01 10:22:14.096090+0100 Paging2[45575:3540067] MyView 0x7fd87fa059a0 didMoveToWindow 0x7fd87f80f3d0
2020-06-01 10:22:14.096511+0100 Paging2[45575:3540067] MyView 0x7fd87fa24160 didMoveToWindow 0x7fd87f80f3d0
2020-06-01 10:22:14.099019+0100 Paging2[45575:3540067] MyView 0x7fd87fa059a0 didMoveToWindow 0x0
2020-06-01 10:22:14.099318+0100 Paging2[45575:3540067] MyView 0x7fd87fa24160 didMoveToWindow 0x0
2020-06-01 10:22:14.099812+0100 Paging2[45575:3540067] MyView 0x7fd87fa059a0 didMoveToWindow 0x7fd87f80f3d0
2020-06-01 10:22:14.100306+0100 Paging2[45575:3540067] MyView 0x7fd87fa24160 didMoveToWindow 0x7fd87f80f3d0

For comparison here is UINavigationController when pushing. I learned in this question that the extra move to window is for the transition, turning on slow animations helps:

2020-06-01 10:49:16.786872+0100 NavWindowTest[45792:3560379] View 0x7fbfba608090 didMoveToWindow 0x0 (current view removed from window)
2020-06-01 10:49:16.787170+0100 NavWindowTest[45792:3560379] View 0x7fbfba608090 didMoveToWindow 0x7fbfba50c150 (current view added to window for transition)
2020-06-01 10:49:16.787577+0100 NavWindowTest[45792:3560379] View 0x7fbfba5124d0 didMoveToWindow 0x7fbfba50c150 (new view added)
2020-06-01 10:49:21.801791+0100 NavWindowTest[45792:3560379] View 0x7fbfba608090 didMoveToWindow 0x0 (old view removed from transition)
2020-06-01 10:49:21.803690+0100 NavWindowTest[45792:3560379] ViewController 0x7fbfbd005dd0 viewDidAppear: 0x7fbfba5124d0

The fact that viewDidAppear is called last when navigating but first in paging makes me think there is a problem.




回答2:


I ended up finding an answer to this question. So, in viewDidAppear I added this:

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

I'm happy to give the checkmark to whoever can explain why this works.



来源:https://stackoverflow.com/questions/43531127/setting-becomefirstresponder-on-viewcontroller-nested-in-pageviewcontroller

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!