A library to recreate the iOS Apple Music now playing transition

Overview

DeckTransition

CI Status Version Package Managers Documentation License Contact

DeckTransition is an attempt to recreate the card-like transition found in the iOS 10 Apple Music and iMessage apps.

Hereʼs a GIF showing it in action.

Demo

Requirements

  • Swift 5.0
  • iOS 9 or later

Installation

CocoaPods

To install DeckTransition using CocoaPods, add the following line to your Podfile:

pod 'DeckTransition', '~> 2.0'

Carthage

To install DeckTransition using Carthage, add the following line to your Cartfile:

github "HarshilShah/DeckTransition" ~> 2.0

Documentation

You can find the docs here. Documentation is generated with Jazzy, and hosted on GitHub Pages.

Usage

Basics

Set modalPresentationCapturesStatusBarAppearance to true in your modal view controller, and override the preferredStatusBarStyle variable to return .lightContent.

Additionally, the UIScrollView instances which should be tracked for the swipe-to-dismiss gesture should have their backgroundColor set to .clear.

Presentation

The transition can be called from code or using a storyboard.

To use via storyboards, just setup a custom segue (kind set to custom), and set the class to DeckSegue.

Hereʼs a snippet showing usage via code. Just replace ModalViewController() with your view controller's class and youʼre good to go.

let modal = ModalViewController()
let transitionDelegate = DeckTransitioningDelegate()
modal.transitioningDelegate = transitionDelegate
modal.modalPresentationStyle = .custom
present(modal, animated: true, completion: nil)

Dismissal

By default, DeckTransition has a swipe-to-dismiss gesture which is automatically enabled when your modalʼs main UIScrollView is scrolled to the top.

You can opt-out of this behaviour by passing in false for the isSwipeToDismissEnabled parameter while initialising your DeckTransitioningDelegate.

UIScrollView detection

DeckTransition has an internal heuristic to determine which UIScrollView should be tracked for the swipe-to-dismiss gesture. In general, this should be sufficient for and cover most use cases.

However there are some edge cases, and should you run into one, these can we worked around by making your modal view controller conform to the DeckTransitionViewControllerProtocol protocol. More information about this can be found in the documentation page about UIScrollView detection.

Snapshots

For a variety of reasons, and especially because of iOS 11's safe area layout, DeckTransition uses a snapshot of your presenting view controller's view instead of using the view directly. This view is automatically updated whenever the frame is resized.

However, there can be some cases where you might want to update the snapshot view by yourself, and this can be achieved using the following one line snippet:

(presentationController as? DeckSnapshotUpdater)?.requestPresentedViewSnapshotUpdate()

All this does is request the presentation controller to update the snapshot.

You can also choose to update snapshot directly from the presenting view controller, as follows:

(presentedViewController?.presentationController as? DeckSnapshotUpdater)?.requestPresentedViewSnapshotUpdate()

It's worth noting that updating the snapshot is an expensive process and should only be used if necessary, for example if you are updating your entire app's theme.

Apps Using DeckTransition

Feel free to submit a PR if you’re using this library in your apps

Author

Written by Harshil Shah

License

DeckTransition is available under the MIT license. See the LICENSE file for more info.

Comments
  • In-Call Status Bar Issue

    In-Call Status Bar Issue

    It seems there's two issues when there's an in-call status bar with a taller height. First, the status bar covers up the presented view controller's top part.

    Second, after dismissing the presented modal, the presented view controller isn't being reset correctly. To reproduce, on the demo toggle in-call status bar, present the modal, take the app to background and bring it back. Now the presented view controller's frame is wrong. It's something to do with the transform, but I haven't figured it out yet.. On my own app, the controller's frame is actually going off screen (e.g. too large) after the modal is dismissed

    opened by hamedh 21
  • Table view scroll

    Table view scroll

    I have implemented your scroll view code to my table view controller and it will dismiss when I’m not at the top. Do you have any suggestions?

    Also when it said set the scroll view delegate as self, I just made sure tableview.delegate equaled self. Is that correct?

    opened by carson-katri 12
  • Init method not visible to ObjC

    Init method not visible to ObjC

    You seem to be using optional parameters within the constructors which can't be bridged to ObjC. Thus this library is not usable in ObjC projects.

    See: https://stackoverflow.com/questions/26470771/swift-init-not-visible-in-objecitve-c

    opened by heyarny 11
  • Added presentedVC top offset customisation option

    Added presentedVC top offset customisation option

    I wanted to be able to customise the top offset of the presented ViewController, so I've added in a new property in the DeckTransitioningDelegate and DeckPresentationController, that allows for this.

    It is an optional argument to the existing constructors, that defaults to 28. Existing call sites will not be affected.

    Because the top offset could be large enough that the user could tap on the background, I've also added a tap gesture to dismiss the modal by tapping there.

    Regards, Arvindh

    opened by arvindhsukumar 10
  • Dragging past threshold closes view even if finger does not let go.

    Dragging past threshold closes view even if finger does not let go.

    I noticed that if you drag the view past the threshold to dismiss it, you can't drag your finger back if you don't let go to cancel it.

    It's a bit frustrating if you drag it down to "peek" underneath, and then it closes. Just running some tests here to examine the functionality and noticed this.

    opened by benguild 9
  • StatusBar appearance doesn't change using storyboards...

    StatusBar appearance doesn't change using storyboards...

    In your example file you are creating an object of ModalViewController and present this view controller via present(_:animated:completion:) after transitioningDelegate and modalPresentationStyle are set. This works as expected. The statusBar appearance changes with the transition from default to lightContent and then back to default again when dismissing.

    But creating a storyboard segue by following the instructions in your README file (line 51) and perform the segue by invoking performSegue(withIdentifier:sender) doesn't change the statusBar appearance as expected. It keeps its default value. I couldn't figure out why.

    Tested on Xcode 9GM simulator with iOS 11, iPhone 7+8.

    opened by Bem44 9
  • NavBar Glitch

    NavBar Glitch

    This glitch appends when the View Controller is not the top-level VC of a Navigation Controller (when you've got a Back Button in the navBar etc.) When the Modal Controller is pushed, the navBar of the previous ViewController is cropped from the top. glitch

    opened by sushimatou 9
  • Carthage support

    Carthage support

    Hey! Matt from WWDCSCholars here :)

    You sent me this library a few days ago. It looks neat! But we were wondering, could you please add Carthage support so we can actually implement it in the app, without too much hassle?

    opened by matthijs2704 9
  • Modal not appearing in segue

    Modal not appearing in segue

    Hi there.

    Really want to use DeckTransition but it isn't working for me. I'm using a dark background and an embedded UIView with a tap gesture recogniser.

    Please can you help me.

    opened by g30r93g 8
  • releasing scrollViewUpdater on pan .ended, to stop observing

    releasing scrollViewUpdater on pan .ended, to stop observing

    This prevents crashing if DeckPresentationController contains a table view, since scrollViewUpdater observes contentOffset and results in crash when table view displayed is eventually released while still having this KVO observer:

    Fatal Exception: NSInternalInconsistencyException An instance 0x132094a00 of class UITableView was deallocated while key value observers were still registered with it. Current observation info: <NSKeyValueObservationInfo 0x174626680> ( <NSKeyValueObservance 0x17485da60: Observer: 0x175e74cc0, Key path: contentOffset, Options: <New: NO, Old: NO, Prior: NO> Context: 0x0, Property: 0x170a50890> )

    opened by soreshko 7
  • Bug on hidesBarsOnTap

    Bug on hidesBarsOnTap

    Hello Harshil Shah! Thanks a lot of what are you doing!! In ios11 I found interesting bug. On hiding navigation bar on tap it disappears like on foto. Can you help with this?

    screen shot 2017-12-19 at 7 53 49 pm screen shot 2017-12-19 at 7 54 03 pm
    opened by Bronko44 7
  • Zombie

    Zombie

    Hello. I've used DeckTransition for a while, but I have ipod with ios 9.3.5. And I'v caught Zombie object. Снимок экрана 2020-07-09 в 12 20 02

    The same app on the simulator (ios >= 11.0) or iPhone (ios >= 11.0) works fine.

    opened by sapgv 2
  • Keyboard hide laggy when present deck

    Keyboard hide laggy when present deck

    I am integrating this lib into my project and it works perfect until I got this problem with keyboard:

    • setup a viewcontroller with textfield and keyboard is showing
    • click on a button to present this new viewcontroller with this decktransition. The keyboard will hide automatically but very laggy

    The keyboard is glitching/laggy when hiding. I am sure it is this lib because I compare this lib with ios default presenting modal view.

    I hope this one could be fixed because this glitching make smooth animation become glitchy

    opened by pvn-anh-pham 4
  • DeckTransition 3.0

    DeckTransition 3.0

    Hey all,

    Sorry it’s been a while, this took a bit longer than I’d expected, and then iOS 13 hit and that made it take a bit longer.

    Originally, I was planning address some different issues with this major update, however in light of the transition changes in iOS 13, I’ve had to made some changes to the plans. While custom transitions and variable height presentations were to be the main focus, I’ve decided to push those back in favour of prioritising bringing the design and implementation up to par with Apple’s.

    The goal for now is to essentially make DeckTransition functionally identical to the default iOS 13 transitions which will enable backporting the new UI for now, and then building in features which Apple doesn’t have yet such as the two mentioned above, better customisability on iPads, and so on.

    Here’s a list of all the changes I’m hoping to get in:

    • The swipe-to-dismiss gesture should use an interactive transition.
    • View controllers should be able to dynamically specify when a dismissal is allowed.
    • The corner radius handling needs improvement. On devices and features with rounded corners (so the X-series iPhones, newer iPad Pros, and split view on iPads) the presenting card should animate from the device’s corners.
    • The iPad UI needs a complete rethink. It should essentially be a 1:1 match of Apple’s designs which scales up from a page sheet to the current style based on the user’s dynamic type settings.

    The iPhone part of this changelog is relatively trivial. The iPad part will take significant work, especially given the smart things Apple is doing with handling corner radii in split view, for example.

    Additionally, I think I’ve found solutions to some prevalent bugs such as the weird transforms for certain UITableView rows and some others.

    It should be possible to retain support for upto iOS 11, however iOS 9 and 10 will likely have to be dropped.

    The plan is to have a draft of this change in within a few weeks, time permitting.

    I’d love to hear any thoughts people using this library have about these planned changes or any ideas.

    opened by HarshilShah 5
  • Rotation breaks the layout

    Rotation breaks the layout

    In my app I have a UISplitViewController as the base. Now, when I present a UIViewController as a card on top of it, the view will look like this.

    image

    However, when I rotate the device and then rotate back, the layout breaks and it will look like this.

    image

    When I then rotate once more and once more back, the app will crash, throwing this:

    Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Multiplier is not finite!  That's illegal.  multiplier:-inf'
    *** First throw call stack:
    (
    0   CoreFoundation                      0x000000010759a6fb __exceptionPreprocess + 331
    1   libobjc.A.dylib                     0x0000000106b3eac5 objc_exception_throw + 48
    2   CoreFoundation                      0x000000010759a482 +[NSException raise:format:arguments:] + 98
    3   Foundation                          0x000000010658c927 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 194
    4   Foundation                          0x000000010679255e -[NSLayoutConstraint _setMultiplier:] + 336
    5   Foundation                          0x000000010679949f +[NSLayoutConstraint constraintWithAnchor:relatedBy:toAnchor:multiplier:constant:] + 575
    6   DeckTransition                      0x000000010319992b $s14DeckTransition0A22PresentationControllerC29updateSnapshotViewAspectRatio33_71FA53A27BEAE2D482201C2CF371A196LLyyF + 1931
    7   DeckTransition                      0x000000010319a09a $s14DeckTransition0A22PresentationControllerC31containerViewWillLayoutSubviewsyyF + 298
    8   DeckTransition                      0x000000010319a644 $s14DeckTransition0A22PresentationControllerC31containerViewWillLayoutSubviewsyyFTo + 36
    9   UIKitCore                           0x0000000111070905 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 1229
    

    Any ideas as to what could be causing this? I have a feeling it's a layout issue in the library, but I have no clue where to start looking...

    opened by Sjoerdjanssenen 2
Releases(2.2.0)
  • 2.2.0(Sep 1, 2019)

  • 2.1.0(Sep 17, 2018)

  • 2.0.0(Dec 8, 2017)

    DeckTransition is now at version 2.0! 🎉

    This is a major API upgrade. The previous API which required UIScrollViewDelegate conformance has been entirely removed, and is replaced by an automatic UIScrollView detection mechanism.

    API Breaking Changes

    • The isDismissEnabled property on DeckTransitioningDelegate is removed. This behaviour is now managed automatically, which means that your old dismissal code is no longer needed and can be removed entirely, and your existing view controllers should "just work" in most cases.

      There exist some edge cases with the new mechanism, more about which, including workarounds, can be found in the documentationʼs new UIScrollView detection guide.

    Other Changes

    • A new isSwipeToDismissEnabled parameter is added to the DeckTransitioningDelegate initializer, to disable the swipe-to-dismiss gesture entirely, if need be. This is set to true by default and requires no change to retain previous behaviour.
    Source code(tar.gz)
    Source code(zip)
  • 1.4.2(Nov 12, 2017)

  • 1.4.1(Nov 8, 2017)

  • 1.4.0(Oct 21, 2017)

    • Updated animations to work much better when presenting mutliple view controllers using DeckTransition
    • Fixes an issue where the appearance method calls were sometimes unbalanced
    Source code(tar.gz)
    Source code(zip)
  • 1.3.4(Oct 13, 2017)

  • 1.3.3(Oct 13, 2017)

    This is the last version of this framework to support Swift 3.x. Further development will be done on Swift 4.x

    • Corner rounding is now animated
    Source code(tar.gz)
    Source code(zip)
  • 1.3.2(Sep 30, 2017)

  • 1.3.1(Sep 26, 2017)

  • 1.3.0(Sep 22, 2017)

  • 1.2.0(Sep 22, 2017)

  • 1.1.0(Sep 15, 2017)

  • 1.0.4(Sep 15, 2017)

  • 1.0.3(Sep 15, 2017)

  • 1.0.2(Aug 25, 2017)

  • 1.0.1(Aug 5, 2017)

  • 1.0.0(Aug 5, 2017)

    Here’s a summary of all the changes in this version

    • Vastly improved performance
    • Reorganized project structure
    • Support for Carthage
    • All “magic numbers” have been refactored out

    One small change needs to be implemented in pre-1.0 projects to maintain compatibility with this version of DeckTransition. The entirety of the change consists of replacing the following line of code in your modal view controller’s UIScrollViewDelegate implementation

    scrollView.transform = CGAffineTransform(translationX: 0, y: scrollView.contentOffset.y)
    

    with the block that follows below:

    scrollView.subviews.forEach {
        $0.transform = CGAffineTransform(translationX: 0, y: scrollView.contentOffset.y)
    }
    

    The implementation example in the ReadMe has been updated to reflect this.

    Source code(tar.gz)
    Source code(zip)
  • 0.4.0(Aug 2, 2017)

    API Breaking Changes

    • The DeckTransitioningDelegate initialiser now requires NSNumber arguments for animation duration
    • A snapshot of the presenting view controller is shown instead of the view itself

    Other Changes

    • Fixed Objective-C compatibility issues
    • Fixed a host of bugs related to the double height status bar and rotation
    • You can now use pod try to try the library
    Source code(tar.gz)
    Source code(zip)
  • 0.3.0(May 14, 2017)

    The transition can now be customised by passing in custom animation durations, other animations to be performed alongside the stock animation, and completion handlers

    Source code(tar.gz)
    Source code(zip)
  • 0.2.0(Aug 2, 2017)

  • 0.1.2(Aug 2, 2017)

  • 0.1.1(Aug 2, 2017)

Owner
Harshil Shah
I make apps and stuff
Harshil Shah
SpriteKit Floating Bubble Picker (inspired by Apple Music) 🧲

Magnetic Magnetic is a customizable bubble picker like the Apple Music genre selection. Demo Video $ pod try Magnetic Features Adding/Removing Nodes

Lasha Efremidze 1.4k Jan 6, 2023
A drop-in universal library helps you to manage the navigation bar styles and makes transition animations smooth between different navigation bar styles

A drop-in universal library helps you to manage the navigation bar styles and makes transition animations smooth between different navigation bar styles while pushing or popping a view controller for all orientations. And you don't need to write any line of code for it, it all happens automatically.

Zhouqi Mo 3.3k Dec 21, 2022
Cool Animated music indicator view written in Swift

Cool Animated music indicator view written in Swift. ESTMusicIndicator is an implementation of NAKPlaybackIndicatorView in Swift for iOS 8. 本人著作的书籍《La

Aufree 465 Nov 28, 2022
UI Component. This is a copy swipe-panel from app: Apple Maps, Stocks. Swift version

ContainerController UI Component. This is a copy swipe-panel from app: https://www.apple.com/ios/maps/ Preview Requirements Installation CocoaPods Swi

Rustam 419 Dec 12, 2022
Kit for building custom gauges + easy reproducible Apple's style ring gauges.

GaugeKit ##Kit for building custom gauges + easy reproducible Apple's style ring gauges. -> Example Usage Open GaugeKit.xcworkspace and change the sch

Petr Korolev 1k Dec 23, 2022
A fancy hexagonal layout for displaying data like your Apple Watch

Hexacon is a new way to display content in your app like the Apple Watch SpringBoard Highly inspired by the work of lmmenge. Special thanks to zenly f

Gautier Gédoux 340 Dec 4, 2022
Apple TV Parallax effect in Swift.

MPParallaxView Apple TV Parallax effect in Swift. Rotate view using touch or accelerometer. Usage To run the example project, clone the repo, and run

Droids On Roids 1.7k Jan 4, 2023
Iridescent Effect View (inspired by Apple Pay Cash) ✨

Shiny Shiny is an iOS library that generates an iridescent effect view matched to the gyroscope, similar to the Apple Pay Cash card in the Wallet app.

Lasha Efremidze 768 Dec 2, 2022
Flutter Apple Product Store App UI Home Page With Getx

Flutter Apple Product Store App UI Home Page With Getx A new Flutter UI Project on my Youtube Channel . About The Project Create a beautiful Flutter U

Muawia Saeed 11 Dec 23, 2022
Bubble pickers, inspired by Apple

AmazingBubbles Bubble pickers, inspired by Apple Requirements: iOS 9.1+ XCode 8.0+ Swift 3.0 Installation AmazingBubbles Library is available through

Gleb Radchenko 63 Oct 14, 2022
DrawerKit lets an UIViewController modally present another UIViewController in a manner similar to the way Apple's Maps app works.

DrawerKit What is DrawerKit? DrawerKit is a custom view controller presentation mimicking the kind of behaviour in the Apple Maps app. It lets any vie

Babylon Health 773 Dec 27, 2022
BulletinBoard is an iOS library that generates and manages contextual cards displayed at the bottom of the screen

BulletinBoard is an iOS library that generates and manages contextual cards displayed at the bottom of the screen. It is especially well

Alexis (Aubry) Akers 5.3k Jan 2, 2023
⚡️ A library of widgets and helpers to build instant-search applications on iOS.

By Algolia. InstantSearch family: InstantSearch iOS | InstantSearch Android | React InstantSearch | InstantSearch.js | Angular InstantSearch | Vue Ins

Algolia 567 Dec 20, 2022
Non-intrusive iOS UI library to implement overlay based interfaces

OverlayContainer is a UI library written in Swift. It makes easier to develop overlay based interfaces, such as the one presented in the Apple Maps, S

Applidium 1k Jan 4, 2023
An iOS Library that makes shadows management easy on UIView.

ShadowView is an iOS Shadow library that makes view's shadow implementation easy and sweet ?? ?? . Add simple shadows to add a gaussian blurred projec

Pierre 404 Dec 8, 2022
StarryStars is iOS GUI library for displaying and editing ratings

StarryStars StarryStars is iOS GUI library for displaying and editing ratings Features StarryStars' RatingView is both IBDesignable and IBInspectable

Peter Prokop 175 Nov 19, 2022
A library to imitate the iOS 10 Maps UI.

Pulley A library to imitate the drawer in Maps for iOS 10/11. The master branch follows the latest currently released version of Swift. If you need an

52inc 2k Dec 29, 2022
A nice iOS View Capture Swift Library which can capture all content.

SwViewCapture A nice iOS View Capture Library which can capture all content. SwViewCapture could convert all content of UIWebView to a UIImage. 一个用起来还

Xing Chen 597 Nov 22, 2022