正在加载视频...
视频加载失败
Custom view controller transition I built at work this week. A few interesting engineering challenges… 1) Presenting the half sheet during the custom transition. 2) Animating the frame/transform of an MKMapView! 3) Ensuring continuity of the activity indicator before/after the transition begins/ends. Details below 👇🏽
11 条评论

1) UIKit has an interesting limitation which is that a presented view controller cannot present another view controller itself until its presentation animation is complete. The work around here was to create a UIView subclass with a single subview of type UIWindow. UIWindow is, itself, just a UIView subclass - so it can be treated like any other UIView. From here, you can set the window’s rootViewController and tell it to present any view controller you like, without animation. A few considerations to make: a) You’ll need to override the view hosting the window’s hitTest(_:with:) method to ignore all touches outside the presented sheet. This way, the map view below can still be interacted with. b) You’ll need to manually set the window’s traitCollection and safeAreaInsets as, unlike other UIView subclasses, UIWindow does not inherit these properties from its superview. c) If you’re presenting UIMenus from this additional window, you’ll need to dismiss them manually when a touch is registered outside the bounds of the menu. You can do this in the overridden hitTest(_:with:) method.

2) Animating the MKMapView was particularly tricky. For some reason, annotations and overlays would end up in the wrong position, and they’d jump around when the transition completed. The solution was to not animate the map view at all. Instead, I used a _UIPortalView during the transition. This view is created using the initWithSourceView: initialiser and composites the supplied sourceView and all of its subviews into a single CALayer. Then, I animated the portal view’s frame and transform, keeping the original map view unaltered - works a charm!

3) Ensuring continuity between the activity indicator at the start of the transition, during the transition, and at the end of the transition is key to making the illusion of a custom view controller transition work. If the progress of spinner were to jump around, it would break the illusion. The fix? Simple… Rather than starting the animation of the spinner based on when it was added to the view hierarchy, use a CADisplayLink to base the rotational transform off 1 radian divided by the millisecond on the device’s clock. Here’s UIView.animate versus CADisplayLink…

Looking good! The only thing that bothers me a bit is the top gradient blur that should (IMHO) progressively fade in once the transition is almost complete instead of being visible immediately. But that’s barely noticeable at normal speed. Great work 👏

That’s not a bad idea actually… Will resist the urge to do this until Monday though 😉

King of details! It looks so smooth!

Thanks Fran 🙏🏽

amazing! disappointed though that there aren’t any private APIs here 😔

Haha thanks Eslam! Did you read the thread below? Hint hint… 👀

so beautiful transition 🤩

Thank you friend 🙏🏽

