- July 26, 2025
- Mins Read
Easy to use UIPageViewController to create a view navigation like Snapchat/Tinder/iOS Main Pages.
You can use CocoaPods to install EZSwipeController
by adding it to your Podfile
:
platform :ios, ‘8.0’
use_frameworks!
pod ‘EZSwipeController’
import EZSwipeController
Carthage is a decentralized dependency manager that automates the process of adding frameworks to your Cocoa application.
You can install Carthage with Homebrew using the following command:
$ brew update
$ brew install carthage
To integrate EZSwipeController into your Xcode project using Carthage, specify it in your Cartfile
:
github “goktugyil/EZSwipeController”
Run carthage update
.
$ carthage update
You can also use EZSwipeController via push or present on your UIViewcontrollers like:
presentViewController(EZSwipeController(), animated: true, completion: nil)
If you want to use EZSwipe as root viewcontroller (Your apps starting point):
Go to Targets -> Your Target -> General -> Main Interface -> Delete it
Add this to your AppDelegate:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
window = UIWindow(frame: UIScreen.main.bounds)
window!.rootViewController = MySwipeVC()
window!.makeKeyAndVisible()
return true
}
import UIKit
// import EZSwipeController // if using CocoaPods
class MySwipeVC: EZSwipeController {
override func setupView() {
datasource = self
}
}
extension MySwipeVC: EZSwipeControllerDataSource {
func viewControllerData() -> [UIViewController] {
let redVC = UIViewController()
redVC.view.backgroundColor = UIColor.red
let blueVC = UIViewController()
blueVC.view.backgroundColor = UIColor.blue
let greenVC = UIViewController()
greenVC.view.backgroundColor = UIColor.green
return [redVC, blueVC, greenVC]
}
}
You should have something like this:
class MySwipeVC: EZSwipeController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.yellowColor()
}
}
extension MySwipeVC: EZSwipeControllerDataSource {
func titlesForPages() -> [String] {
return [“red”, “blue”, “green”]
}
}
extension MySwipeVC: EZSwipeControllerDataSource {
func indexOfStartingPage() -> Int {
return 2 // EZSwipeController starts from 2nd, green page
}
}
extension MySwipeVC: EZSwipeControllerDataSource {
func changedToPageIndex(index: Int) {
// You can do anything from here, for now we’ll just print the new index
print(index)
}
}
Setting up navigationBarDataForPageIndex overrides effects in titlesForPages.
extension MySwipeVC: EZSwipeControllerDataSource {
func navigationBarDataForPageIndex(index: Int) -> UINavigationBar {
var title = “”
if index == 0 {
title = “Charmander”
} else if index == 1 {
title = “Squirtle”
} else if index == 2 {
title = “Bulbasaur”
}
let navigationBar = UINavigationBar()
navigationBar.barStyle = UIBarStyle.Default
// navigationBar.barTintColor = QorumColors.WhiteLight
print(navigationBar.barTintColor)
navigationBar.titleTextAttributes = [NSForegroundColorAttributeName: UIColor.blackColor()]
let navigationItem = UINavigationItem(title: title)
navigationItem.hidesBackButton = true
if index == 0 {
let rightButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Search, target: self, action: “a”)
rightButtonItem.tintColor = UIColor.blackColor()
navigationItem.leftBarButtonItem = nil
navigationItem.rightBarButtonItem = rightButtonItem
} else if index == 1 {
let rightButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Bookmarks, target: self, action: “a”)
rightButtonItem.tintColor = UIColor.blackColor()
let leftButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Camera, target: self, action: “a”)
leftButtonItem.tintColor = UIColor.blackColor()
navigationItem.leftBarButtonItem = leftButtonItem
navigationItem.rightBarButtonItem = rightButtonItem
} else if index == 2 {
let leftButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Search, target: self, action: “a”)
leftButtonItem.tintColor = UIColor.blackColor()
navigationItem.leftBarButtonItem = leftButtonItem
navigationItem.rightBarButtonItem = nil
}
navigationBar.pushNavigationItem(navigationItem, animated: false)
return navigationBar
}
}
You don’t need to set actions to buttons, EZSwipeController automatically overrides them and makes them work.
extension MySwipeVC: EZSwipeControllerDataSource {
func navigationBarDataForPageIndex(index: Int) -> UINavigationBar {
var title = “”
if index == 0 {
title = “Charmander”
} else if index == 1 {
title = “Squirtle”
} else if index == 2 {
title = “Bulbasaur”
}
let navigationBar = UINavigationBar()
navigationBar.barStyle = UIBarStyle.Default
navigationBar.barTintColor = UIColor.purpleColor()
navigationBar.titleTextAttributes = [NSForegroundColorAttributeName: UIColor.blackColor()]
let navigationItem = UINavigationItem(title: title)
navigationItem.hidesBackButton = true
if index == 0 {
var sImage = UIImage(named: “squir”)!
sImage = scaleTo(image: sImage, w: 22, h: 22)
let rightButtonItem = UIBarButtonItem(image: sImage, style: UIBarButtonItemStyle.Plain, target: self, action: “a”)
rightButtonItem.tintColor = UIColor.blueColor()
navigationItem.leftBarButtonItem = nil
navigationItem.rightBarButtonItem = rightButtonItem
} else if index == 1 {
var cImage = UIImage(named: “char”)!
cImage = scaleTo(image: cImage, w: 22, h: 22)
let leftButtonItem = UIBarButtonItem(image: cImage, style: UIBarButtonItemStyle.Plain, target: self, action: “a”)
leftButtonItem.tintColor = UIColor.redColor()
var bImage = UIImage(named: “bulb”)!
bImage = scaleTo(image: bImage, w: 22, h: 22)
let rightButtonItem = UIBarButtonItem(image: bImage, style: UIBarButtonItemStyle.Plain, target: self, action: “a”)
rightButtonItem.tintColor = UIColor.greenColor()
navigationItem.leftBarButtonItem = leftButtonItem
navigationItem.rightBarButtonItem = rightButtonItem
} else if index == 2 {
var sImage = UIImage(named: “squir”)!
sImage = scaleTo(image: sImage, w: 22, h: 22)
let leftButtonItem = UIBarButtonItem(image: sImage, style: UIBarButtonItemStyle.Plain, target: self, action: “a”)
leftButtonItem.tintColor = UIColor.blueColor()
navigationItem.leftBarButtonItem = leftButtonItem
navigationItem.rightBarButtonItem = nil
}
navigationBar.pushNavigationItem(navigationItem, animated: false)
return navigationBar
}
}
private func scaleTo(image image: UIImage, w: CGFloat, h: CGFloat) -> UIImage {
let newSize = CGSize(width: w, height: h)
UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0)
image.drawInRect(CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height))
let newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage
}
Sometimes you may want to add your own actions to buttons, in that case you should disable the default button behaviour:
extension MySwipeVC: EZSwipeControllerDataSource {
func disableSwipingForLeftButtonAtPageIndex(index: Int) -> Bool {
if index == 1 {
return true
}
return false
}
func clickedLeftButtonFromPageIndex(index: Int) {
if index == 1 {
print(“What!?! Squirtle is evolving!!”)
}
}
}
You can also add your analytics and other stuff in here.
class MySwipeVC: EZSwipeController {
override func setupView() {
super.setupView()
datasource = self
navigationBarShouldBeOnBottom = true
}
}
class MySwipeVC: EZSwipeController {
override func setupView() {
super.setupView()
datasource = self
self.moveToPage(0)
}
}
class MySwipeVC: EZSwipeController {
override func setupView() {
super.setupView()
navigationBarShouldNotExist = true
}
}
override func setupView() {
cancelStandardButtonEvents()
// Use this setting if you are using custom button that
// has nothing to do with swiping the viewcontroller
}
self.currentVCIndex
//Use this to get the current page index
TODO
s inside source filesNavigationKit is a lightweight library which makes SwiftUI navigation super easy to use. 💻 Installation 📦 Swift Package Manager Using Swift Package Manager, add ...
An alternative SwiftUI NavigationView implementing classic stack-based navigation giving also some more control on animations and programmatic navigation. NavigationStack Installation ...
With SwiftUI Router you can power your SwiftUI app with path-based routing. By utilizing a path-based system, navigation in your app becomes ...
This package takes SwiftUI's familiar and powerful NavigationStack API and gives it superpowers, allowing you to use the same API not just ...