По умолчанию, когда представлен контроллер представления, UIKit удаляет представляющие VC после завершения анимации.Представление VC-представления временно добавляется к представлению контейнера только во время перехода.
Это поведение можно изменить с помощью UIModalPresentationStyle.overFullScreen
или shouldRemovePresentersView в случае пользовательской презентации.В этом случае только представленное представление перемещается во временное containerView
, и вся анимация выполняется над представлением существующего VC - ни одно из нижних представлений не обрабатывается.
Здесь вы выполняете fullScreen
переход над ВК представлен пользовательским переходом.UIKit сохраняет иерархию представлений нетронутой и перемещает только представление виртуального контейнера представления (фиолетовое) вместе с представлением виртуального канала (красного цвета) в представление контейнера во время переходов увольнения и представления.Затем он удаляет фиолетовый после завершения анимации.
Проблема, по-видимому (я использовал точки останова в методах didMoveToSuperview
& setFrame
), когда происходит переход при увольнении, по умолчанию «встроенный»Контроллер анимации не заботится о предыдущем кадре представления VC, когда он временно добавляет его в containerView
.Он устанавливает его в рамку containerView сразу после перехода к containerView
.
Я не знаю, является ли это ошибкой или преднамеренным выбором.
Вот код, который я использовал:
class BottomVCView: UIView {
override var frame: CGRect {
set {
super.frame = newValue // BREAKPOINT : newValue.height == 568.0
}
get {
return super.frame
}
}
}
class BottomVC: UIViewController {
lazy var myView = BottomVCView()
override func loadView() {
view = BottomVCView()
}
}
А вот стек, в котором UIViewControllerBuiltinTransitionViewAnimator
устанавливает кадр представления VC-представления.
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
* frame #0: 0x0000000102ca0ce8 Project`BottomVCView.frame.setter(newValue=(origin = (x = 0, y = 0), size = (width = 320, height = 568)), self=0x00007ffde5e059f0) at ViewController.swift:35:13
frame #1: 0x0000000102ca0c9f Project`@objc BottomVCView.frame.setter at <compiler-generated>:0
frame #2: 0x0000000108e2004f UIKitCore`-[UIViewControllerBuiltinTransitionViewAnimator animateTransition:] + 1149
frame #3: 0x0000000108d17985 UIKitCore`__56-[UIPresentationController runTransitionForCurrentState]_block_invoke + 3088
frame #4: 0x0000000109404cc9 UIKitCore`_runAfterCACommitDeferredBlocks + 318
frame #5: 0x00000001093f4199 UIKitCore`_cleanUpAfterCAFlushAndRunDeferredBlocks + 358
frame #6: 0x000000010942132b UIKitCore`_afterCACommitHandler + 124
frame #7: 0x00000001056fe0f7 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
frame #8: 0x00000001056f85be CoreFoundation`__CFRunLoopDoObservers + 430
frame #9: 0x00000001056f8c31 CoreFoundation`__CFRunLoopRun + 1505
frame #10: 0x00000001056f8302 CoreFoundation`CFRunLoopRunSpecific + 626
frame #11: 0x000000010d0dd2fe GraphicsServices`GSEventRunModal + 65
frame #12: 0x00000001093f9ba2 UIKitCore`UIApplicationMain + 140
frame #13: 0x0000000102ca60fb NavBar`main at AppDelegate.swift:12:7
frame #14: 0x0000000106b9f541 libdyld.dylib`start + 1
frame #15: 0x0000000106b9f541 libdyld.dylib`start + 1
Если вы используете containerViewWillLayoutSubviews
, вы можете установить рамку пурпурного вида обратно вего правильное значение, но оно будет происходить только после того, как будет выполнен переход отклонения, и представление будет удалено из fullScreen
перехода containerView:
class PresentBottom: UIPresentationController {
override func containerViewWillLayoutSubviews() {
super.containerViewWillLayoutSubviews()
presentedView?.frame = frameOfPresentedViewInContainerView
}
}
Я думаю, вы можете просто использовать:
let VC = UIViewController()
VC.view.backgroundColor = .red
VC.modalPresentationStyle = .overFullScreen
Чтобы сохранить всю иерархию представления на месте.Аниматор не будет касаться представления текущего ВК - viewController(for: .from)
возвращает ноль, так как его представление не перемещается в представление контейнера.