It's been a really long time since I've tried this, so I'm not sure if something has changed or if I've stumbled onto a bug...
I'm trying to implement a custom Transition Animation for a UINavigationController. While documentation around this is pretty sparse this days, I was able to take the old sample from the View Controller Programming Guide:, rewriting it in Swift:
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
let containerView = transitionContext.containerView
guard let fromVC = transitionContext.viewController(forKey: .from),
let toVC = transitionContext.viewController(forKey: .to),
let toView = transitionContext.view(forKey: .to),
let fromView = transitionContext.view(forKey: .from) else {
transitionContext.completeTransition(false)
return
}
let containerFrame = containerView.frame
var toViewStartFrame = transitionContext.initialFrame(for: toVC)
let toViewFinalFrame = transitionContext.finalFrame(for: toVC)
var fromViewFinalFrame = transitionContext.finalFrame(for: fromVC)
let fromViewStartFrame = transitionContext.initialFrame(for: fromVC)
if operation.isPresenting {
toViewStartFrame.origin.x = containerFrame.size.width
toViewStartFrame.origin.y = containerFrame.size.height
} else {
fromViewFinalFrame = CGRect(x: containerFrame.size.width,
y: containerFrame.size.height,
width: toView.frame.size.width,
height: toView.frame.size.height)
// missing from Apple's sample code
toViewStartFrame = toViewFinalFrame
}
containerView.addSubview(toView)
toView.frame = toViewStartFrame
// Add the from view to the container view on dismissal, this is missing from Apple's sample code
if !operation.isPresenting {
containerView.addSubview(fromView)
fromView.frame = fromViewStartFrame
}
UIView.animate(withDuration: transitionDuration(using: transitionContext)) {
if self.operation.isPresenting {
toView.frame = toViewFinalFrame
} else {
fromView.frame = fromViewFinalFrame
}
} completion: { completed in
let success = !transitionContext.transitionWasCancelled
if (self.operation.isPresenting && !success) || (!self.operation.isPresenting && success) {
toView.removeFromSuperview()
}
// missing from Apple's sample code
if !self.operation.isPresenting {
fromView.removeFromSuperview()
}
transitionContext.completeTransition(success)
}
}
I added a couple of things to support dismissals and pops.
In order to use it with in my app, I set the navigation controller's delegate and returned the type conforming to UIViewControllerAnimatedTransitioning, containing the above code, from navigationController(_ :, animationControllerFor operation:, from fromVC:, to toVC). I've confirmed that that all behaves as you expect.
If I use this animation controller for a modal presentation or dismissal, it works fine. For a Navigation push, again, behaves as expected. But when I use it for a navigation pop I run into a problem. The animation is performed, but once it completes, the Navigation Controller's view appears to be completely empty. In a sample app, the screen goes black. In the View Debugger, I see that the UIViewControllerWrapperView has no subviews. Another curious thing I found is that my View Controller never gets a viewWillDisappear message sent.
Is there an additional setup step that I missed in order to get this working properly?
Post
Replies
Boosts
Views
Activity
Any insight on how I can add support for the Outer Ring "jog" gesture that is new on the Apple TV 4K Siri Remote? This was demo'd during the Apple Special event earlier this year.
I do know that access to taps on the TouchPad is a little esoteric so curious if anybody's figured this out. Haven't seen it documented anywhere.