Carthage compatible Version Platform Build Status codecov Reviewed by Hound Language Packagist

Fluidable

A Swift library that allows you to create a custom transition conforming to Fluid Interfaces.

Features & To-Do

  • [x] Support UINavigationControllerDelegate and UIViewControllerTransitioningDelegate
  • [x] Interactive and intrruptible transition with UIScrollView, UITableView, and UICollectionView
  • [x] Additional animations for view controllers that can be defined in the delegate method (supports both UIViewPropertyAnimator andCore Animation)
  • [x] Monitor transition states and progress with delegate methods
  • [x] Customizable presentation style (Fluid, Drawer, and Slide)
  • [x] Resizable drawer
  • [x] Customizable style (rounded corner, shadow, and background effect)
  • [x] Customizable animation easing and duration
  • [ ] Interact with underlying views like Apple Maps
  • [ ] Custom transitions with user-definable plug-ins
  • [ ] Support iOS 10
Fluid Drawer Slide

Requirements

  • iOS 11.0 or later
  • Swift 4.2

Installation

Carthage

Add the following to your Cartfile and follow these instructions.

github "gumob/Fluidable"

CocoaPods

To integrate Fluidable into your project, add the following to your Podfile.

platform :ios, '10.0'
use_frameworks!

pod 'Fluidable'

Example application

Repository contains example sources under Example directory. Structure of the application is simple, but the project contains mutiple case of UI petterns to showcase capabilities of the library. You can build an example app by choosing FluidableExample from the Xcode schemes.

Usage

Full documentation is available at https://gumob.github.io/Fluidable/.
You can find more specific implementations by searching the Example sources with `IMPORTANT: 🌊`.

Custom transition using UIViewControllerTransitioningDelegate

1) Import Fluidable framework to your project files:

import UIKit
import Fluidable

2) Initialze Fluidable framework in AppDelegate:

class AppDelegate: UIResponder, UIApplicationDelegate {
  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
      FluidableInit()
      return true
  }
}

3) Conform to Fluidable protocol in the source view controller:

class RootViewController: UICollectionViewController, Fluidable {
  required init?(coder aDecoder: NSCoder) {
      super.init(coder: aDecoder)
      self.fluidDelegate = self
  }
}

4) Conform to FluidTransitionSourceConfigurationDelegate and FluidTransitionSourceActionDelegate protocols in the source view controller:

extension RootViewController: FluidTransitionSourceConfigurationDelegate {
  /* Implement delegate methods */
}
extension RootViewController: FluidTransitionSourceActionDelegate {
  /* Implement delegate methods */
}

5) Conform to Fluidable protocol in the destination view controller:

class TransitionScrollViewController: TransitionBaseViewController, Fluidable {
  var fluidableTransitionDelegate: FluidViewControllerTransitioningDelegate = FluidViewControllerTransitioningDelegate()
  required init?(coder aDecoder: NSCoder) {
      super.init(coder: aDecoder)
        self.transitioningDelegate = self.fluidableTransitionDelegate
        self.fluidDelegate = self
  }
}

6) Conform to FluidTransitionDestinationConfigurationDelegate and FluidTransitionDestinationActionDelegate protocols in the destination view controller:

extension TransitionScrollViewController: FluidTransitionDestinationConfigurationDelegate {
  /* Implement delegate methods */
}
extension TransitionScrollViewController: FluidTransitionDestinationActionDelegate {
  /* Implement delegate methods */
}

Custom transition using UINavigationControllerDelegate

1) Import Fluidable framework to your project files:

import UIKit
import Fluidable

2) Initialze Fluidable framework in AppDelegate:

class AppDelegate: UIResponder, UIApplicationDelegate {
  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
      FluidableInit()
      return true
  }
}

3) Conform to Fluidable protocol in the source view controller:

class RootViewController: UICollectionViewController, Fluidable {
  required init?(coder aDecoder: NSCoder) {
      super.init(coder: aDecoder)
      self.fluidDelegate = self
  }
}

4) Conform to FluidTransitionSourceConfigurationDelegate and FluidTransitionSourceActionDelegate protocols in the source view controller:

extension RootViewController: FluidTransitionSourceConfigurationDelegate {
  /* Implement delegate methods */
}
extension RootViewController: FluidTransitionSourceActionDelegate {
  /* Implement delegate methods */
}

5) Conform to Fluidable protocol in the destination view controller:

class TransitionScrollViewController: TransitionBaseViewController, Fluidable {
  var fluidableTransitionDelegate: FluidViewControllerTransitioningDelegate = FluidViewControllerTransitioningDelegate()
  required init?(coder aDecoder: NSCoder) {
      super.init(coder: aDecoder)
        self.transitioningDelegate = self.fluidableTransitionDelegate
        self.fluidDelegate = self
  }
}

6) Conform to FluidTransitionDestinationConfigurationDelegate and FluidTransitionDestinationActionDelegate protocols in the destination view controller:

extension TransitionScrollViewController: FluidTransitionDestinationConfigurationDelegate {
  /* Implement delegate methods */
}
extension TransitionScrollViewController: FluidTransitionDestinationActionDelegate {
  /* Implement delegate methods */
}

Resizable drawer

The FluidResizableTransitionDelegate is available for only bottom drawer.

1) Conform to FluidResizableTransitionDelegate protocol in the destination view controller:

class TransitionScrollViewController: TransitionBaseViewController, Fluidable, FluidResizable {
  required init?(coder aDecoder: NSCoder) {
      super.init(coder: aDecoder)
      self.transitioningDelegate = self.fluidableTransitionDelegate
      self.fluidDelegate = self
      self.fluidResizableDelegate = self
  }
}

extension TransitionScrollViewController: FluidResizableTransitionDelegate {
    func transitionShouldPerformResizing() -> Bool { return true }
    func transitionMinimumMarginForResizing() -> CGFloat { return 64 }
    func transitionSnapPositionsForResizing() -> [CGFloat]? { return [0.0, 0.5, 1.0] }
    func transitionInteractiveResizeDidProgress(state: FluidProgressState, position: CGFloat, info: FluidGestureInfo) {
    }
}

Fluidable is released under MIT license, which means you can modify it, redistribute it or use it however you like.

All image embedded in the example project are downloaded from Pexels.