One thing I've noticed on tvOS 26 is that if you try to set the AVPlayerViewController customInfoViewControllers property while the Content Tabs are on screen, your app will crash.
*** Terminating app due to uncaught exception 'UIViewControllerHierarchyInconsistency', reason: 'trying to add child view controller that is already presented: <AVInfoPanelViewController: 0x1030cdc00>'
*** First throw call stack:
(0x18a7167bc 0x189a77510 0x18a7166a8 0x1ab425658 0x1b2ee9d54 0x1b2efcd60 0x1b2eaf3f0 0x1080f744c 0x107e021a8 0x107e01b3c 0x18de41c14 0x18de41ba8 0x18de48d28 0x18ad9e358 0x101fac5f0 0x101fc6228 0x101fe7278 0x101fbc6fc 0x101fbc63c 0x18a67a2e0 0x18a679418 0x18a673b34 0x1937e4d5c 0x1abb36588 0x1abb3ae80 0x1aae9dec4 0x108610174 0x1086100e4 0x108615140 0x189abd4d0)
I've logged a feedback (FB19554461) but it's getting awfully late in the dev cycle. So I've been trying to think of a workaround.
The problem is that customInfoViewControllers is pretty declarative in nature. There are no properties or delegate methods I am aware of that let me know when they are displaying or not.
One trick I came up with was seeing if my custom info view controller's view was "visible" or not - I put that in quotes because it turns out it can be visible even when I think it's not, as when the transport bar is scrolled to the top my custom VC still has its top pixels showing, so it gets a viewDidAppear call. So, I tried to see if my view controllers view is completely visible, ie based on the results of the GGRect contains method. And that works! But the problem is it only accounts for my own custom info view controllers, and not the standard one that Apple provides. I can't think of a way at all to know whether that is showing.
Any ideas?
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
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?
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.