问题
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