your3i’s blog

iOSエンジニア。頑張る⚉

iOS QuickLook like Interactive Transition for Dismissal - Part 1

What is a QuickLook like transition?

QuickLook is a framework used to preview files like images, videos and many other kind of files in iOS SDK.

So many iOS pre-installed apps are using this framework. The most commonly used among them must be the "Photos" app. In the "Photos" app, if you preview a photo and want to dismiss it, you will swipe the photo. ( I think most users barely tap the "Back" button 🤔)

Maybe it's just so natural that you don't even notice what happened. Let's break the transition into small pieces.

When you swipe to dismiss ...
  • The image seems to stick to your finger moves
  • The image's size changes as your finger moves
  • The dimming view's alpha changes as your finger moves
  • When you release, the image is animated to the position and size of its thumbnail image in the previous screen or back to its original position and size if the transition is not occurred.
Example

It's from a demo project that I was working on lately.

f:id:your3i:20181126233848g:plain:w300

Why I wrote this post

I didn't find anything useful that could help me understand the process. So, hope it might be some help to some others.

Actually it's kinda introduced in WWDC2016 #216. Even though the tutorial is not complete, it had been a great help. Thanks a lot to one of the speakers. There's a moment he accidentally showed some other parts of the code and it helped me figure out what should be done.

Advances in UIKit Animations and Transitions - WWDC 2016 - Videos - Apple Developer

How (the short version)

Before you start

I suppose you understand how to make a custom transition. That means, for example, you know what a transition context is and what a container view is. If you don't, check here to learn more.

What's the difference

... difference between a simple dismissal transition and an interactive dismissal transition.

f:id:your3i:20181128230238p:plain
Difference between simple no-stop transition and interactive transition

The secrets of this interactive dismissal transition

If you know how to make a simple custom transition, I guess what would confuse you the most to make an interactive "Photos" app like dismissal transition are these questions... (which confused me the most)

What is the sticking view moving around with your finger?
It's a temporarily created view. It's put into the container view when transition starts. It doesn't belong to any of the view controllers' views.

How does it know what position and what size to animate to as you release your finger?
Since transition context only knows fromViewController's view and toViewController's view, you have to pass these data from outside to the transition controller or whatever should be in charge of this.

Is the "moving around" a part of the transition?
Strictly speaking, it is. The pan gesture triggers the transition so when you're moving around the view, view controllers are in transition. But the "moving around" is not a part of the transition animation. It's used to scrub the transition animation and you can continue the rest of the animation when it's over.

Is the dimming view animation and moved-around view animation (when pan gesture is over) one animation?
No. Actually they are two separate animations. The dimming view animation is the transition animation to scrub. And the moved-around view animation is just another animation that ends precisely as the transition animation ends.

All in all, what we need to do is ...
To prepare the container view to the ⬇︎ state as the transition starts and animate them as we want.

f:id:your3i:20181202135026p:plain
container view in dismissal transition

The animations:

f:id:your3i:20181202144407p:plain
the dismissal animations

How (the detailed version)

I planned to include the detailed version in this post but it would be too long and ... , in that case, no idea when I could complete this post 😇

So check out the repo if you want !

Related files:

  • ImageViewerController.swift
  • ImageViewerInteractiveTransitionController.swift
  • ImageViewerPanTracker.swift
  • ImageViewerTransitionDriver.swift

( Hope I could write another post when I figure out how to make it simple and easy to understand)