Giter Site home page Giter Site logo

sebastianboldt / jelly Goto Github PK

View Code? Open in Web Editor NEW
2.4K 38.0 121.0 53.99 MB

๐ŸŒŠ - Jelly is a library for animated, non-interactive & interactive viewcontroller transitions and presentations with the focus on a simple and yet flexible API.

Home Page: http://www.sebastianboldt.com/

License: MIT License

Swift 98.29% Ruby 1.71%
uikit uiviewcontroller animations viewcontroller-transition uipresentationcontroller swift ios

jelly's Introduction

Jelly-Animators: Elegant Viewcontroller Animations in Swift

current version current version twitter handle Swift 4.2 compatible platform SPM-Compatible carthage support license

Jelly is a library for animated, non-interactive & interactive viewcontroller
transitions and presentations with the focus on a simple and yet flexible API.

With a few lines of source code, interactive UIViewController transitions
and custom resizable UIViewController presentations can be created,
without the use of the cumbersome UIKit Transitioning API.

var slidePresentation = SlidePresentation(direction: .left)
let animator = Animator(presentation: slidePresentation)
animator.prepare(viewController: viewController)
present(viewController, animated: true, completion: nil)

  1. Create a Presentation Object
  2. Configure an Animator with the Presentation
  3. Call the prepare Function
  4. Use the native UIViewController presentation function.
class ViewController : UIViewController {
    var animator: Jelly.Animator?
    override func viewDidLoad() {
        super.viewDidLoad()
        let viewController = YourViewController()
        let presentation = SlidePresentation(direction: .left)
        animator = Animator(presentation:presentation)
        animator?.prepare(presentedViewController: viewController)
        present(viewController, animated: true, completion: nil)
    }
}

DO NOT FORGET TO KEEP A STRONG ๐Ÿ’ช REFERENCE

Because the transitioningDelegate of a UIViewController is weak, you need to hold a strong reference to the Animator inside the UIViewController you are presenting from or the central object that maintains your presentations.

Interactive transitions can be activated for the slide and the cover transitions. If the transitions are to be interactive, only an InteractionConfiguration object has to be passed to the presentation.

Here 3 parameters play an important role. First, the completionThreshold, which determines the percentage of the animation that is automatically completed as soon as the user finishes the interaction. The second parameter is the actual type of interaction. Jelly offers the .edge and the .canvas type. In an .edge transition, the user must execute the gesture from the edge of the screen. When using the .canvas type, gesture recognizers are configured so that direct interaction with the presenting and presented view leads to the transition. The last parameter is called mode. Using the mode you can limit the interaction to presentation or dismiss interaction (default = [.present,.dismiss]).

let viewController = YourViewController()
let interaction = InteractionConfiguration(presentingViewController: self, completionThreshold: 0.5, dragMode: .edge, mode: .dismiss)
let presentation = SlidePresentation(direction: .right, interactionConfiguration: interaction)
let animator = Animator(presentation: presentation)
animator.prepare(presentedViewController: viewController)

Jelly 2.0 also provides a new feature called LIVE UPDATE. Using Jellys new Live Update API it is now possible to update the alignment, size, margin-guards and corner radius when the viewcontroller is already visible.

These are the new live update functions provided by the Animator.

  • updateAlignment(alignment: PresentationAlignment, duration: Duration) - Cover & Fade
  • updateVerticalAlignment(alignment: VerticalAlignment, duration: Duration) - Cover & Fade
  • updateHorizontalAlignment(alignment: HorizontalAlignment, duration: Duration) - Cover & Fade
  • updateSize(presentationSize: PresentationSize, duration: Duration) - Cover & Fade
  • updateWidth(width: Size, duration: Duration) - Cover, Fade and horizontal Slide
  • updateHeight(height: Size, duration: Duration) - Cover, Fade and vertical Slide
  • updateMarginGuards(marginGuards: UIEdgeInsets, duration: Duration) - Cover & Fade
  • updateCorners(radius: CGFloat, corners: CACornerMask, duration: Duration) - Cover & Fade & Slide

Some of them will throw an exception if used on a not supported presentationType.
For example: It is currently not possible to update the size on a Slide-Presentation.

The presentation types can be configured with various settings:

  • size
  • margin guards
  • direction
  • horizontal & vertical alignment
  • dimmed and blurred backgroundStyle
  • duration
  • presentation and dismiss curve
  • spring damping & velocity
  • corner specification & corner radius
  • completion threshold
  • interactive drag mode (edge or pan)
  • interaction mode (present, dismiss)
  • parallax (Just available on slide Presentations)

Each component is explained in more detail in the Jelly Wiki.

Deployment target of your App is >= iOS 11.0

Jelly is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod 'Jelly', '~> 2.2.2'

or use SPM

Sebastian Boldt, https://www.sebastianboldt.com

I am a mobile software architect and developer specializing in iOS. Passionate about creating awesome user experiences, designing beautiful user interfaces, and writing maintainable, structured, and best-practice orientated code. Continuously trying to improve skills and learn new technologies.

current version

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

jelly's People

Contributors

artemnovichkov avatar baveku avatar bidadh avatar danshevluk avatar jessehao avatar piotr-sekara avatar plarson avatar roczhang9673 avatar sebastianboldt avatar ymkim50 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jelly's Issues

Push 2.2.0 to the trunk

This is just a simple reminder because trunk pushing is currently not enabled because they are moving to a CDN.

viewWillDisappear never called

Hi,

Thanks for your repo. Before I used Jelly viewWillDisappear was called. Now with Jelly viewWillDisappear never called! Any help?

override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        print("Hey")
}

UIModalPresentationCustom Always present On UIWindow.rootViewController

hi there, I come with a question that, I found with option UIModalPresentationCustom, the presented view controller is always presented on UIWindow.rooViewController. I have no idea to present it on any other specific view contoller.
I have tested proprety definesPresentationContext, It seems only work with option UIModalPresentationCurrentContext or UIModalPresentationOverCurrentContext to provide the presenting view controller.

Edge drag available after dismiss called

I am using following way to present my view controller:

let navController = UINavigationController(rootViewController: vc)

let interactionConfiguration = InteractionConfiguration(presentingViewController: self, dragMode: .edge)
let presentation = SlidePresentation(direction: .right, interactionConfiguration: interactionConfiguration)

self.animator = Animator(presentation: presentation)
self.animator?.prepare(presentedViewController: navController)
self.present(navController, animated: true)

It is working fine, sliding from right to left and edge drag is working too.

However after I call self.dismiss(animated: true) in the pushed VC I can still drag the VC back from right edge.

Is there a way to prevent that?

Help for my requirement using this beautiful library.

I want to show a custom designed timer control with blurredslidein or fadin effect.

The design is roughly like, Three label for Hour, Minute & Second. Two button like, Start & Cancel.

Cancel button should disappear the viewController. Start button starts the timer.

So, I just want to ask whether it is possible or not?

Why we need this variable

Hi,
file -> Jelly/Jelly/Classes/JellyAnimator.swift
line -> 16
private weak var viewController : UIViewController?

Why we need this variable?

Adjust height automatically with in-call status bar

Is there any way we can automatically adjust the height/top of the presented view controller when in-call status bar is displayed/hidden? You can check the screenshots for reference.

jelly-in-call-status-bar-issue

Here I've set the size of the presented view controller to be offset 20 from all sides from main screen bounds. I'm using JellySlideInPresentation with following settings:

let presentation = JellySlideInPresentation(
            dismissCurve: .easeInEaseOut,
            presentationCurve: .easeInEaseOut,
            cornerRadius: 4,
            backgroundStyle: .dimmed(alpha: 0.8),
            jellyness: .jelly,
            duration: .normal,
            directionShow: .bottom,
            directionDismiss: .bottom,
            widthForViewController: .custom(value: targetSize.width),
            heightForViewController: .custom(value: targetSize.height),
            horizontalAlignment: .center,
            verticalAlignment: .center,
            marginGuards: .zero,
            corners: .allCorners)

Please let me know if this is achievable.

Write Tests.

There are no tests yet which is really really sad.

How to resize the view of the presented controller ?

let controllerA = ControllerA()
let navigationController = UINavigationController(rootViewController: controllerA)

let presentation = JellyFadeInPresentation()
let animator = JellyAnimator(presentation: presentation)
animator.prepare(viewController: navigationController)

self.present(navigationController, animated: true, completion: nil)

In controllerA, controllerB will be created and pushed to navigationController. My question is How to resize controllerB's view ? Thanks!

Add Shiftin Animation

It would be great to have a shift in Animation that has full height or width depending of the directions it slides in. Some kind of parallex effect would be awesome too.

iOS 13 support

When using the current beta of Xcode a lot of things are broken for some unknown reason so far.
It would be nice to evaluate these issues and fix them.

Flashing blur effect when swiping up on top of controller

Love the library! Literally makes life so much easier. Currently seeing a flash whenever a user swipes up from the top of the controller inside the animator when using the blur effect. Let me know what info would help, I can attach pics or a video.

Possibility to have custom position in the screen

Is it possible to have a custom position similar to the custom in size

Currently, the only way is to have .top, .bottom, .center as listed below I'm wondering if you could add custom like the following:

    public enum VerticalAlignment {
        case top
        case bottom
        case center
        case custom(y: CGFloat) 
    }

    public enum HorizontalAlignment {
        case left
        case right
        case center
        case custom(x: CGFloat) 
    }

I need to display the new viewController at a certain x,y

invalid custom dimmed

In the JellyPresentationController, line 33.

the custom value of dimmed not set to the method setupDimmingView()

"isTapBackgroundToDismissEnabled" is no avaliable

I set the property isTapBackgroundToDismissEnabled false, but seems to no effect
Here is my code:
var presentation = JellySlideInPresentation(cornerRadius: 5.0,widthForViewController: .custom(value: 300),heightForViewController:.custom(value: 260))

presentation.directionShow = .left presentation.directionDismiss = .right

presentation.isTapBackgroundToDismissEnabled = false

let animator = JellyAnimator(presentation: presentation) self.jellyAnimator = animator

let serviceTypeViewController = ServiceTypeViewController() self.jellyAnimator?.prepare(viewController: serviceTypeViewController) self.present(serviceTypeViewController, animated: true, completion: nil)

Add a better way for the user to provide sizes for the Animator

Currently a user needs to specify a custom Size to the JellyPresentation Object. It would be better Idea to create some Kind of size enum that provides the following cases: full, half and custom. We also need to change the init function to expect separate width and height values. As a result the user can more easily create rich transitions.

Perspective on background controller

Thank you for your nice library!
It would be good to have another effect on transition

The following example create a presentation from bottom to up leaving a small portion of screen free on top.

var presentation = JellySlideInPresentation()
presentation.presentationCurve = .easeInEaseOut
presentation.heightForViewController = JellyConstants.Size.custom(value: UIScreen.main.bounds.size.height - 60.0)
presentation.directionShow = .bottom
presentation.verticalAlignemt = .bottom
presentation.directionDismiss = .bottom
presentation.jellyness = .jelly
presentation.isTapBackgroundToDismissEnabled = true
let animator = JellyAnimator(presentation: presentation)
animator.prepare(viewController: modal_navigation)

I would to see the background controller showed in perspective (a little smaller)

vn2cq

Support preferredStatusBarStyle

I can see my status bar being white instead of dark after presenting new ViewController. If I remove the Jelly related code and present it via native code it will respect the default dark style.

Is there some workaround for this?

User should be able to enable or disable background tap dismissal

Currently, it is not possible to enable or disable the background tap that dismisses the viewController.
A JellyPresentation Object should provide an option for that, so users of Jelly can decide by their own, if background typ dimissal should happen or not.

Having a few issues upgarding

Couple issues while upgrading

When running the exact example in the wiki for customizable options shown below

let allCorners = [.layerMaxXMaxYCorner,.layerMaxXMinYCorner,.layerMinXMaxYCorner,.layerMinXMinYCorner]

let uiConfiguration = PresentationUIConfiguration(cornerRadius: 10, 
                                                  backgroundStyle: .blurred(effectStyle: .dark),           
                                                  isTapBackgroundToDismissEnabled: true, 
                                                  corners: allCorners )

let size = PresentationSize(width: .fullscreen, height: .fullscreen)

let alignment = PresentationAlignment(vertical: .center, horizontal: .center)

let marginGuards = UIEdgeInsets(top: 40, left: 16, bottom: 40, right: 16)

let timing = PresentationTiming(duration: .normal, presentationCurve: .linear, dismissCurve: .linear)

let interactionConfiguration = InteractionConfiguration(presentingViewController: self, 
                                                        completionThreshold: 0.5, 
                                                        dragMode: .canvas)

let presentation = CoverPresentation(directionShow: .left, 
                                     directionDismiss: .left, 
                                     uiConfiguration: uiConfiguration, 
                                     size: size, 
                                     alignment: alignment, 
                                     marginGuards: marginGuards, 
                                     timing: timing, 
                                     spring: .none, 
                                     interactionConfiguration: interactionConfiguration)

I had to hint to the compiler it was an options set with

let allCorners: CACornerMask = [.layerMaxXMaxYCorner,.layerMaxXMinYCorner,.layerMinXMaxYCorner,.layerMinXMinYCorner]

I'm also not sure how to migrate old usage to new usage, for example:

var presentation = JellySlideInPresentation()
presentation.widthForViewController = .custom(value: 295)
presentation.heightForViewController = .custom(value: 173)

The new signature of SlidePresentation takes a size of type Size where CoverPresentation takes a size of PresentationSize, so i'm not sure what to do here

Interactive Transitions

I'm trying to use the interactive transition to dismiss a view controller when swiping downward. I'm still a little confused to how to get access to the gesture recognizer. Am I suppose to use the new Live Update API in conjunction with the gesture recognizer, or what am I doing wrong?

iOS 13 glitch issue

I am presenting my ViewControllers this way by using different PresentationSize and PresentationUIConfiguration.
Presenting this way and its creating glitches every where.

let vc = UIStoryboard(name: "RideSelectionStory", bundle: nil).instantiateInitialViewController() as! RideSelectionVC
let interactionConfiguration = InteractionConfiguration(presentingViewController: self, completionThreshold: 0.5, dragMode: .edge)
let uiConfiguration = PresentationUIConfiguration(cornerRadius: 0, backgroundStyle: .dimmed(alpha: 0.92), isTapBackgroundToDismissEnabled: false)
let size = PresentationSize(width: .fullscreen, height: .custom(value: (self.view.frame.height*0.7)))
let marginGuards = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
let alignment = PresentationAlignment(vertical: .bottom, horizontal: .left)
let presentation = CoverPresentation(directionShow: .bottom, directionDismiss: .bottom, uiConfiguration: uiConfiguration, size: size, alignment: alignment, marginGuards: marginGuards, interactionConfiguration: interactionConfiguration)
let animator = Animator(presentation: presentation)
self.animator = animator
animator.prepare(presentedViewController: vc)
self.present(vc,animated: true)

and it is giving a glitch on iOS 13. What can be the solution for this issue?

RetainCycle issue!

I used this library in a project, and I realized that viewControllers that presented by Jelly, will NOT deinitialized!

I just added this, to Example project of the library:

// DismissMeController.swift
class DismissMeController: UIViewController {

    deinit {
        print("DismissMeController.Deinit?!")
    }
    ...
}

the message is NOT printing after dismissing viewController.

Hide status bar for presented ViewControllers?

@SebastianBoldt, Is there a way to hide the status bar for a presented ViewController, like a slide-in, for example? I've overriden prefersStatusBarHidden in the VC being presented by Jelly, but that's not doing the trick. Any help is appreciated. Thanks for the great tool!

John

Request to put back Minimum deployment target to iOS 10

@SebastianBoldt Thank you for this great library!

Can you please explain for which reasons other than for using the maskedCorners property of the CALayer is the minimum deployment target set to iOS 11?

Although iOS 10 is not recent anymore, users are still using it and if you bring back support you will be covering close to 99% of all users.

All this requires a simple change. One similar provided by this gist

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.