A Swift library that allows you to create a custom transition conforming to Fluid Interfaces.
- Support
UINavigationControllerDelegate
andUIViewControllerTransitioningDelegate
- Interactive and intrruptible transition with
UIScrollView
,UITableView
, andUICollectionView
- Additional animations for view controllers that can be defined in the delegate method (supports both
UIViewPropertyAnimator
andCore Animation
) - Monitor transition states and progress with delegate methods
- Customizable presentation style (Fluid, Drawer, and Slide)
- Resizable drawer
- Customizable style (rounded corner, shadow, and background effect)
- 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 |
---|---|---|
- iOS 10.0 or later
- Swift 5.0
Add the following to your Cartfile
and follow these instructions.
github "gumob/Fluidable"
To integrate Fluidable into your project, add the following to your Podfile
.
platform :ios, '10.0'
use_frameworks!
pod 'Fluidable'
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.
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
- Import
Fluidable
framework to your project files:
import UIKit
import Fluidable
- Initialze
Fluidable
framework inAppDelegate
:
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
FluidableInit()
return true
}
}
- 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
}
}
- Conform to
FluidTransitionSourceConfigurationDelegate
andFluidTransitionSourceActionDelegate
protocols in the source view controller:
extension RootViewController: FluidTransitionSourceConfigurationDelegate {
/* Implement delegate methods */
}
extension RootViewController: FluidTransitionSourceActionDelegate {
/* Implement delegate methods */
}
- 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
}
}
- Conform to
FluidTransitionDestinationConfigurationDelegate
andFluidTransitionDestinationActionDelegate
protocols in the destination view controller:
extension TransitionScrollViewController: FluidTransitionDestinationConfigurationDelegate {
/* Implement delegate methods */
}
extension TransitionScrollViewController: FluidTransitionDestinationActionDelegate {
/* Implement delegate methods */
}
Custom transition using UINavigationControllerDelegate
- Import
Fluidable
framework to your project files:
import UIKit
import Fluidable
- Initialze
Fluidable
framework inAppDelegate
:
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
FluidableInit()
return true
}
}
- 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
}
}
- Conform to
FluidTransitionSourceConfigurationDelegate
andFluidTransitionSourceActionDelegate
protocols in the source view controller:
extension RootViewController: FluidTransitionSourceConfigurationDelegate {
/* Implement delegate methods */
}
extension RootViewController: FluidTransitionSourceActionDelegate {
/* Implement delegate methods */
}
- 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
}
}
- Conform to
FluidTransitionDestinationConfigurationDelegate
andFluidTransitionDestinationActionDelegate
protocols in the destination view controller:
extension TransitionScrollViewController: FluidTransitionDestinationConfigurationDelegate {
/* Implement delegate methods */
}
extension TransitionScrollViewController: FluidTransitionDestinationActionDelegate {
/* Implement delegate methods */
}
The FluidResizableTransitionDelegate
is available for only bottom drawer.
- 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.