Post

Replies

Boosts

Views

Created

[iOS 18 Only] Intermittent Crash at completeTransition in Custom Navigation Animation (Firebase Crashlytics)
Hi everyone, I'm encountering an intermittent crash on iOS 18 only (not reproducible locally, reported in Firebase Crashlytics) at transitionContext.completeTransition(!transitionContext.transitionWasCancelled) within my custom UIViewControllerAnimatedTransitioning. The same code runs fine on iOS 16 and 17 (no Crashlytics report for those iOS version) Here's the crash log: Crashed: com.apple.main-thread 0 libswiftCore.dylib 0x4391f0 swift_getObjectType + 40 1 ROOM 0x490c48 ItemDetailAnimator.navigationController(_:animationControllerFor:from:to:) + 47 (ItemDetailAnimator.swift:47) 2 ROOM 0x490f3c @objc ItemDetailAnimator.navigationController(_:animationControllerFor:from:to:) + 92 (<compiler-generated>:92) 3 UIKitCore 0xa2d7a4 -[UINavigationController _customTransitionController:] + 516 4 UIKitCore 0x2e51dc -[UINavigationController _immediatelyApplyViewControllers:transition:animated:operation:] + 2620 5 UIKitCore 0x1541d4 __94-[UINavigationController _applyViewControllers:transition:animated:operation:rescheduleBlock:]_block_invoke + 100 6 UIKitCore 0x150768 -[UINavigationController _applyViewControllers:transition:animated:operation:rescheduleBlock:] + 776 7 UIKitCore 0x2e7e44 -[UINavigationController pushViewController:transition:forceImmediate:] + 544 8 UIKitCore 0x2e4230 -[UINavigationController pushViewController:animated:] + 444 9 ROOM 0x66cb04 UINavigationController.pushViewController(_:animated:completion:) + 185 (UINavigationController+Room.swift:185) 10 ROOM 0x8cef4c ItemDetailCoordinator.start(animated:completion:) + 99 (ItemDetailCoordinator.swift:99) 11 ROOM 0xc6c95c protocol witness for Coordinator.start(animated:completion:) in conformance BaseCoordinator + 24 (<compiler-generated>:24) 12 ROOM 0x8ca520 AppCoordinator.startCoordinator(_:url:reference:animated:completion:) + 729 (AppCoordinator.swift:729) 13 ROOM 0x8cb248 protocol witness for URLSupportCoordinatorOpener.startCoordinator(_:url:reference:animated:completion:) in conformance AppCoordinator + 48 (<compiler-generated>:48) 14 ROOM 0xd6166c URLSupportCoordinatorOpener<>.open(url:openingController:reference:animated:completion:) + 118 (URLSupportedCoordinator.swift:118) 15 ROOM 0xc56038 RRAppDelegate.handleURL(url:completion:) + 588 (RRAppDelegate.swift:588) 16 ROOM 0xc502d0 RRAppDelegate.applicationDidBecomeActive(_:) + 330 (RRAppDelegate.swift:330) 17 ROOM 0xc5041c @objc RRAppDelegate.applicationDidBecomeActive(_:) + 52 (<compiler-generated>:52) 18 UIKitCore 0x1fb048 -[UIApplication _stopDeactivatingForReason:] + 1368 My animateTransition code is: ```func animateTransition( using transitionContext: UIViewControllerContextTransitioning) { guard let (fromView, toView, fromVC, toVC) = filterTargets(context: transitionContext) else { transitionContext.cancelInteractiveTransition() transitionContext.completeTransition(false) return } let containerView = transitionContext.containerView toView.frame = transitionContext.finalFrame(for: toVC) guard let targetView = fromVC.animationTargetView, let fromFrame = fromVC.animationTargetFrame, let toFrame = toVC.animationTargetFrame else { containerView.insertSubview(toView, aboveSubview: fromView) toView.frame = transitionContext.finalFrame(for: toVC) transitionContext.completeTransition(true) return } let newFromFrame = fromView.convert(fromFrame, to: containerView) let tempImageView: UIImageView if let target = targetView as? UIImageView, let image = targetImage ?? target.image, image.size.height != 0, target.frame.height != 0, image.size.width / image.size.height != target.frame.width / target.frame.height { targetImage = image tempImageView = UIImageView(image: image) tempImageView.frame = newFromFrame tempImageView.contentMode = .scaleAspectFit } else { tempImageView = targetView.room.asImageView() tempImageView.frame = newFromFrame } targetView.isHidden = true let tempFromView = containerView.room.asImageView() targetView.isHidden = false let tempHideView = UIView() containerView.addSubview(tempFromView) containerView.insertSubview(toView, aboveSubview: tempFromView) tempHideView.backgroundColor = .white toView.addSubview(tempHideView) containerView.addSubview(tempImageView) //Minus with item detail view y position //Need to minus navigation bar height of item detail view var tempHideViewFrame = toFrame tempHideViewFrame.origin.y -= toView.frame.origin.y tempHideView.frame = tempHideViewFrame let duration = transitionDuration(using: transitionContext) toView.alpha = 0 UIView.animate(withDuration: duration * 0.5, delay: duration * 0.5, options: .curveLinear, animations: { toView.alpha = 1 }) let scale: CGFloat = toFrame.width / newFromFrame.width let newFrame = CGRect( x: toFrame.minX - newFromFrame.minX * scale, y: toFrame.minY - newFromFrame.minY * scale, width: tempFromView.frame.size.width * scale, height: tempFromView.frame.size.height * scale) UIView.animate(withDuration: duration, delay: 0.0, options: [.curveEaseInOut], animations: { tempFromView.frame = newFrame tempImageView.frame = toFrame }, completion: { _ in tempHideView.removeFromSuperview() tempFromView.removeFromSuperview() tempImageView.removeFromSuperview() transitionContext.completeTransition(!transitionContext.transitionWasCancelled) }) }
4
0
227
Apr ’25