我有一个A
当前处于编辑模式的视图控制器,即它有一个当前是第一响应者的文本字段。
现在我使用自定义动画师展示视图B
控制器A
:
class Animator: NSObject, UIViewControllerAnimatedTransitioning {
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return 1
}
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
print("----- Transition Animation BEGIN -----")
guard let toView = transitionContext.view(forKey: .to) else {
return
}
transitionContext.containerView.addSubview(toView)
print("----- Transition Animation ADDED SUBVIEW -----")
toView.frame = transitionContext.containerView.bounds
toView.layoutIfNeeded()
transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
}
}
为简单起见,这个动画师没有做太多动画:它只是将目标视图控制器的视图添加到层次结构中,仅此而已。
视图控制器B
也有一个文本字段,当它出现在屏幕上时,我希望它立即成为第一响应者。因此,我将此代码添加到视图控制器B
:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
textField.becomeFirstResponder()
}
现在有趣的部分是之间发生了什么
----- Transition Animation BEGIN -----
和
----- Transition Animation ADDED SUBVIEW -----
1. 根视图内部
当视图控制器A
中的文本字段放置在其根视图内的任何位置时,这些是我收到的键盘通知NotificationCenter
:
----- Transition Animation BEGIN -----
UIKeyboardDidChangeFrameNotification
UIKeyboardDidHideNotification
UIKeyboardWillChangeFrameNotification
UIKeyboardWillShowNotification
UIKeyboardDidChangeFrameNotification
UIKeyboardDidShowNotification
----- Transition Animation ADDED SUBVIEW -----
换句话说:将目标视图控制器的视图添加到转换的容器视图会导致所有这些键盘通知被触发。这很棒,因为之后我可以更新B
的布局以考虑键盘并将这些布局更改应用于我的过渡动画。
2. 集合视图单元内部
但是,当文本字段放置在视图控制器的集合视图单元A
中时,在转换期间不会收到键盘通知:
----- Transition Animation BEGIN -----
----- Transition Animation ADDED SUBVIEW -----
无论如何,这些是我在过渡动画开始之前收到的通知:
UIKeyboardWillChangeFrameNotification
UIKeyboardWillHideNotification
这是有问题的,因为在第二种情况下,视图控制器B
仍然“认为”键盘在动画期间是隐藏的。因此,我无法布局其视图并创建正确的动画。