A paging view controller with a highly customizable menu ✨

Overview

Getting Started | Customization | Installation


Cities Example Unsplash Example Calendar Example

Features

Parchment lets you page between view controllers while showing any type of generic indicator that scrolls along with the content. Here are some benefits of using Parchment:

  • Highly customizable
    The menu items are built using UICollectionView, which means you can display pretty much whatever you want. You can even subclass the layout to create completely custom behaviours.

  • Memory-efficient:
    Parchment only allocates view controllers when they’re needed, meaning if you have a lot of view controllers you don’t have to initialize them all up-front.

  • Infinite scrolling:
    Because view controllers are only allocated as you are scrolling, you can create data sources that are infinitely large. This is perfect for things like calendars.

Table of contents

Getting started

Basic usage

Parchment is built around the PagingViewController class. You can initialize it with an array of view controllers and it will display menu items for each view controller using their title property.

let firstViewController = UIViewController()
let secondViewController = UIViewController()

let pagingViewController = PagingViewController(viewControllers: [
  firstViewController,
  secondViewController
])

See more: Basic usage

Data source

Initializing PagingViewController with an array of view controllers is fine in most cases, but if you have more than a few view controllers you probably don't want to allocate them all up-front. If you're going to display a fixed number of view controllers, you can setup your own data source by implementing PagingViewControllerDataSource:

extension ViewController: PagingViewControllerDataSource {
    func numberOfViewControllers(in pagingViewController: PagingViewController) -> Int {
        return 10
    }

    func pagingViewController(_ pagingViewController: PagingViewController, viewControllerAt index: Int) -> UIViewController {
        return ChildViewController(index: index)
    }

    func pagingViewController(_: PagingViewController, pagingItemAt index: Int) -> PagingItem {
        return PagingTitleItem(title: "View \(index)", index: index)
    }
}

Then you need to set the dataSource property and select the initial item:

let pagingViewController = PagingViewController()
pagingViewController.dataSource = self
pagingViewController.select(index: 0)

Using the data source means Parchment will only allocate view controllers for the currently selected item and any of its siblings. This is a lot more memory efficient than using PagingViewController(viewControllers:) if you have many view controllers.

Read more: Using the data source

Infinite data source

Using PagingViewControllerDataSource means you need to know how many view controllers to display. If you’re creating something like a calendar, the number of view controllers can be infinitely large. In that case you can use the PagingViewControllerInfiniteDataSource protocol:

extension ViewController: PagingViewControllerInfiniteDataSource {
    func pagingViewController(_: PagingViewController, viewControllerFor pagingItem: PagingItem) -> UIViewController {
        return ItemViewController(item: pagingItem)
    }

    func pagingViewController(_: PagingViewController, itemBefore pagingItem: PagingItem) -> PagingItem? {
        guard let item = pagingItem as? Item else { return nil }
        return Item(index: item.index - 1)
    }

    func pagingViewController(_ : PagingViewController, itemAfter pagingItem: PagingItem) -> PagingItem? {
        guard let item = pagingItem as? Item else { return nil }
        return Item(index: item.index + 1)
    }
}

Then set the infiniteDataSource property and select the initial item:

let pagingViewController = PagingViewController()
pagingViewController.infiniteDataSource = self
pagingViewController.select(pagingItem: Item(index: 0))

This pattern is very similar to the UIPageViewControllerDataSource protocol. The main difference is that instead of returning view controllers directly, you have to return an instance conforming to the PagingItem protocol. Parchment will recursively call these methods for the selected PagingItem until the available space is filled up.

Read more: Using the infinite data source

Selecting items

You can select items programatically using:

func select(pagingItem: PagingItem, animated: Bool = false)

Let’s say you want to select the first item:

override func viewDidLoad() {
  super.viewDidLoad()
  if let first = pagingViewController.items.first {
    pagingViewController.select(pagingItem: first)
  }
}

Or if you have set the dateSource property, you can select items based on their index:

func select(index: Int, animated: Bool = false)

Reloading data

You can reload data using this method:

func reloadData()

This will keep the previously selected item if it's still part of the updated data. If not, it will select the first item in the list. It will also reload the view controllers displayed in the page view controller. If you only want to reload the menu items, you can use this method:

func reloadMenu()

Calling reloadData() will not work when using PagingViewControllerInfiniteDataSource, as we then need to know what the initial item should be. In that case you should use this method:

func reloadData(around: PagingItem)

This will mark the given paging item as selected and generate new items around it.

Delegate

Parchment provides delegate methods for every step of the transition process through the PagingViewControllerDelegate protocol.

protocol PagingViewControllerDelegate: class {

    func pagingViewController(
        _: PagingViewController,
        isScrollingFromItem currentPagingItem: PagingItem,
        toItem upcomingPagingItem: PagingItem?,
        startingViewController: UIViewController,
        destinationViewController: UIViewController?,
        progress: CGFloat)

    func pagingViewController(
        _: PagingViewController,
        willScrollToItem pagingItem: PagingItem,
        startingViewController: UIViewController,
        destinationViewController: UIViewController)

    func pagingViewController(
        _ pagingViewController: PagingViewController,
        didScrollToItem pagingItem: PagingItem,
        startingViewController: UIViewController?,
        destinationViewController: UIViewController,
        transitionSuccessful: Bool)

    func pagingViewController(
        _ pagingViewController: PagingViewController,
        didSelectItem pagingItem: PagingItem)
}

Size delegate

By default, the size of the menu items is controlled by the menuItemSize property. If you need to control width of each menu item individually you can use the PagingControllerSizeDelegate protocol:

protocol PagingViewControllerSizeDelegate: class {
    func pagingViewController(
        _: PagingViewController,
        widthForPagingItem pagingItem: PagingItem,
        isSelected: Bool) -> CGFloat
}

Then set the sizeDelegate on the PagingViewController:

let pagingViewController = PagingViewController()
pagingViewController.sizeDelegate = self

Customization

Parchment is built to be very flexible. The menu items are displayed using UICollectionView, so they can display pretty much whatever you want. If you need any further customization you can even subclass the collection view layout. All customization is handled by the properties listed below.

Custom cells

To use custom cells you need to subclass PagingCell and register the cell type for a given PagingItem:

let pagingViewController = PagingViewController()
pagingViewController.register(CalendarPagingCell.self, for: CalendarItem.self)

Parchment will then dequeue your custom cell when you return the given PagingItem in your data source. You can register multiple cell types for different PagingItems.

Properties

All customization properties are set on PagingViewController:

let pagingViewController = PagingViewController()
pagingViewController.menuItemSize = .fixed(width: 40, height: 40)
pagingViewController.menuItemSpacing = 10

menuItemSize

The size of the menu items. When using sizeDelegate the width will be ignored.

enum PagingMenuItemSize {
  case fixed(width: CGFloat, height: CGFloat)

  // Automatically calculate the size of the menu items based on the
  // cells intrinsic content size. Try to come up with an estimated
  // width that's similar to the expected width of the cells.
  case selfSizing(estimatedWidth: CGFloat, height: CGFloat)

  // Tries to fit all menu items inside the bounds of the screen.
  // If the items can't fit, the items will scroll as normal and
  // set the menu items width to `minWidth`.
  case sizeToFit(minWidth: CGFloat, height: CGFloat)
}

Default: .sizeToFit(minWidth: 150, height: 40)

menuItemSpacing

The spacing between the menu items.

Default: 0

menuItemLabelSpacing

The horizontal constraints of menu item label.

Default: 20

menuInsets

The insets around all of the menu items.

Default: UIEdgeInsets()

menuHorizontalAlignment

enum PagingMenuHorizontalAlignment {
  case `default`

  // Allows all paging items to be centered within the paging menu
  // when PagingMenuItemSize is .fixed and the sum of the widths
  // of all the paging items are less than the paging menu
  case center
}

Default: .default

menuTransition

Determine the transition behaviour of menu items while scrolling the content.

enum PagingMenuTransition {
  // Update scroll offset based on how much the content has
  // scrolled. Makes the menu items transition smoothly as you scroll.
  case scrollAlongside

  // Animate the menu item position after a transition has completed.
  case animateAfter
}

Default: .scrollAlongside

menuInteraction

Determine how users can interact with the menu items.

enum PagingMenuInteraction {
  case scrolling
  case swipe
  case none
}

Default: .scrolling

menuLayoutClass

The class type for collection view layout. Override this if you want to use your own subclass of the layout. Setting this property will initialize the new layout type and update the collection view.

Default: PagingCollectionViewLayout.Type

selectedScrollPosition

Determine how the selected menu item should be aligned when it is selected. Effectively the same as the UICollectionViewScrollPosition.

enum PagingSelectedScrollPosition {
  case left
  case right

  // Centers the selected menu item where possible. If the item is
  // to the far left or right, it will not update the scroll position.
  // Effectivly the same as .centeredHorizontally on UIScrollView.
  case preferCentered
}

Default: .preferCentered

indicatorOptions

Add an indicator view to the selected menu item. The indicator width will be equal to the selected menu items width. Insets only apply horizontally.

enum PagingIndicatorOptions {
  case hidden
  case visible(
    height: CGFloat,
    zIndex: Int,
    spacing: UIEdgeInsets,
    insets: UIEdgeInsets)
}

Default:

.visible(
  height: 4,
  zIndex: Int.max,
  spacing: UIEdgeInsets.zero,
  insets: UIEdgeInsets(top: 0, left: 8, bottom: 0, right: 8))

indicatorClass

The class type for the indicator view. Override this if you want your use your own subclass of PagingIndicatorView.

Default: PagingIndicatorView.self

indicatorColor

The background color for the indicator view.

Default: UIColor(red: 3/255, green: 125/255, blue: 233/255, alpha: 1)

borderOptions

Add a border at the bottom of the menu items. The border will be as wide as all the menu items. Insets only apply horizontally.

enum PagingBorderOptions {
  case hidden
  case visible(
    height: CGFloat,
    zIndex: Int,
    insets: UIEdgeInsets)
}

Default:

.visible(
  height: 1,
  zIndex: Int.max - 1,
  insets: UIEdgeInsets(top: 0, left: 8, bottom: 0, right: 8))

borderClass

The class type for the border view. Override this if you want your use your own subclass of PagingBorderView.

Default: PagingBorderView.self

borderColor

The background color for the border view.

Default: UIColor(white: 0.9, alpha: 1)

includeSafeAreaInsets

Updates the content inset for the menu items based on the .safeAreaInsets property.

Default: true

font

The font used for title label on the menu items.

Default: UIFont.systemFont(ofSize: 15, weight: UIFont.Weight.medium)

selectedFont

The font used for title label on the currently selected menu item.

Default: UIFont.systemFont(ofSize: 15, weight: UIFont.Weight.medium)

textColor

The color of the title label on the menu items.

Default: UIColor.black

selectedTextColor

The text color for the currently selected menu item.

Default: UIColor(red: 3/255, green: 125/255, blue: 233/255, alpha: 1)

backgroundColor

The background color for the menu items.

Default: UIColor.white

selectedBackgroundColor

The background color for the selected menu item.

Default: UIColor.clear

menuBackgroundColor

The background color for the view behind the menu items.

Default: UIColor.white

Installation

Parchment will be compatible with the lastest public release of Swift.

Requirements

  • iOS 8.2+
  • Xcode 8.0+

CocoaPods

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

pod 'Parchment', '~> 3.0'

Swift Package Manager

Parchment is available through Swift Package Manager. Add Parchment as a dependency to your Package.swift:

.package(url: "https://github.com/rechsteiner/Parchment", from: "3.0.0")

Carthage

Parchment also supports Carthage. To install it, add the following to your Cartfile:

github "rechsteiner/Parchment" ~> 3.0

See this guide for more details on using Carthage.

Changelog

This can be found in the CHANGELOG file.

Licence

Parchment is released under the MIT license. See LICENSE for details.

Comments
  • Feature request: reload all data

    Feature request: reload all data

    Currently you have only methods "reload around element". What if I need to change the source items and reload all the data (because I don't know how the items were changed)?

    opened by gerchicov-bp 36
  • Disappear on scroll

    Disappear on scroll

    Is there any way to make the paging menu disappear on the scroll. Most of my paging view controllers are collectionviews and I don't like how the content disappears under the menu when I scroll vertically. Is it possible to do this?

    opened by Smiller193 28
  • Paging menu items are not centered initially

    Paging menu items are not centered initially

    I initialized a FixedPagingViewController with two controllers, both with icons. I setup everything inside of viewDidLoad but then I noticed that they are not centered correctly. They only are properly centered after clicking on the other icon or swiping to the other tab. Is this possible a bug? or am I just using it incorrectly

    How it looks Initially screen shot 2017-09-26 at 4 48 36 pm

    After switching to another tab screen shot 2017-09-26 at 4 48 43 pm

    Now you can see it is properly centered screen shot 2017-09-26 at 4 53 13 pm

    Thanks!

    opened by helloimtony 22
  • Cannot build project with Parchment in pods

    Cannot build project with Parchment in pods

    Hello, I've just installed xCode 13 and now cannot build app, errors in Parchment.

    My stack is: xCode 13.0 (13A233) CocoaPods 1.11.2 Parchment (3.0.1)

    Tried pod repo update, pod deintegrate and install again, cleaning derived data - nothing helps.

    Screenshot 2021-09-23 at 12 37 16
    opened by andrii-lisovskiy 17
  • Need to change to next view controller programmatically.

    Need to change to next view controller programmatically.

    I have used the storyboard example to set up pageviewer for two controllers.In first controller i have an button when on clicked it will be scrolled to next page.But i am not able to get set page index for FixedPagingViewController.How to move to next page on custom button click?

    opened by leniyadav 17
  • Delegate not working in infinite case

    Delegate not working in infinite case

    Hi, i just tried to use self size logic in calendar example, I mean use approach in delegate example to have cell size fit to text, but my delegate functions dont fire. Is it possible to have self size cells for infinite usage?

    opened by Narek1994 17
  • Autolayout issue

    Autolayout issue

    I tried to use this library explained in the onboarding page but it gives me a auto-layout warning:

    `[LayoutConstraints] Unable to simultaneously satisfy constraints. Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. ( "<NSLayoutConstraint:0x608000285f00 V:|-(0)-[UICollectionView:0x7f803388e800] (active, names: '|':Parchment.PagingView:0x7f8032d46f50 )>", "<NSLayoutConstraint:0x608000286090 UICollectionView:0x7f803388e800.height == 40 (active)>", "<NSLayoutConstraint:0x608000285690 V:[UICollectionView:0x7f803388e800]-(0)-[UIView:0x7f8032d41970] (active)>", "<NSLayoutConstraint:0x608000282440 V:[UIView:0x7f8032d41970]-(0)-| (active, names: '|':Parchment.PagingView:0x7f8032d46f50 )>", "<NSLayoutConstraint:0x600000292ac0 'UIView-Encapsulated-Layout-Height' Parchment.PagingView:0x7f8032d46f50.height == 0 (active)>" )

    Will attempt to recover by breaking constraint <NSLayoutConstraint:0x608000285690 V:[UICollectionView:0x7f803388e800]-(0)-[UIView:0x7f8032d41970] (active)>

    Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger. The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.`

    opened by serhatsezer 17
  • Weird scrolling bug

    Weird scrolling bug

    Hi! First of all thanks for a great library!

    We recently decided to try and incorporate this into our app since it would suit our needs perfectly. We also added a collapsing header effect with it. So we first made a test project to test it out and just as we had refactored it into our own app we noticed a very strange bug that we just can't seem to pinpoint the problem with. At first we thought maybe its something in our own app but i opened up the test project and its there as well.

    This GIF will show you the issue. Its even worse when we only have one tab/screen. It then even gets hard to scroll down for a refresh properly without triggering this issue.

    parchmentBug

    Do you have any idea as of why and where this might be happening ?

    Sample code for implementation:

    private var pagingViewController = PagingViewController()
    
    pagingViewController.dataSource = self
    pagingViewController.register(PagingCustomCell.self, for: CustomPagingItem.self)
    addChild(pagingViewController)
    pagingViewController.borderOptions = .hidden
    pagingViewController.menuItemSize = .selfSizing(estimatedWidth: 100, height: 40)
    pagingViewController.indicatorClass = CustomIndicatorView.self
    pagingViewController.indicatorOptions = .visible(
        height: 32,
        zIndex: -1,
        spacing: .zero,
        insets: UIEdgeInsets(top: 0, left: 0, bottom: 5, right: 0)
    )
    pagingViewController.indicatorColor = .purple
    pagingViewController.collectionView.contentInset = UIEdgeInsets(top: 0, left: 16, bottom: 0, right: 16)
    
    view.addSubview(pagingViewController.view)
    pagingViewController.backgroundColor = .clear
    pagingViewController.didMove(toParent: self)
    pagingViewController.view.translatesAutoresizingMaskIntoConstraints = false
    pagingViewController.view.snp.makeConstraints { (m) in
        m.top.equalTo(headerView.snp.bottom)
        m.left.right.bottom.equalToSuperview()
    }
    
    // Put shadow beneath tabs for collapsing header
    pagingViewController.collectionView.layer.masksToBounds = true
    pagingViewController.collectionView.layer.shadowOffset = CGSize(width: 0, height: 1)
    pagingViewController.collectionView.layer.shadowRadius = 1
    pagingViewController.collectionView.layer.shadowOpacity = 0.3
    
    extension ViewController: PagingViewControllerDataSource {
        
        func numberOfViewControllers(in pagingViewController: PagingViewController) -> Int {
            return pages.count
        }
        
        func pagingViewController(_: PagingViewController, viewControllerAt index: Int) -> UIViewController {
            let currentVc = pages[index]
            
            if let currentVc = currentVc {
                return currentVc
            } else {
                let tableViewVC = TableViewController()
                tableViewVC.innerTableViewScrollDelegate = self
                
                pages[index] = tableViewVC
                
                return tableViewVC
            }
        }
        
        func pagingViewController(_: PagingViewController, pagingItemAt index: Int) -> PagingItem {
            return CustomPagingItem(index: index, text: "View \(index+1)")
        }
    }
    
    opened by peter-szucs 16
  • Weird Issue with Indexes

    Weird Issue with Indexes

    Im not sure if this is an error or not but is the library supposed to load two indexes at a time? Everytime I select one it loads the index right next to it. For example if i select index 1 it loads the content for index 2. Is this library supposed to load so many times?

    opened by Smiller193 12
  • Get current controller with InfiniteDataSource

    Get current controller with InfiniteDataSource

    Hi, congratulations for the framework! I'm using the InfiniteDataSource. I can set the variables of controller during the initial setting.

    `extension ContainerViewController: PagingViewControllerInfiniteDataSource {

    func pagingViewController<T>(_ pagingViewController: PagingViewController<T>, viewControllerForPagingItem pagingItem: T) -> UIViewController {
        let calendarItem = pagingItem as! CalendarItem
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let currentController = storyboard.instantiateViewController(withIdentifier: "CollectionViewController") as! CollectionViewController
        currentController.currentDate = calendarItem.date
        currentController.delegate = self
        return currentController
    }
    

    ...`

    How can I communicate with the current controller later?

    Thanks

    opened by mimmo00 12
  • Paging items do not get resized properly after reloading data

    Paging items do not get resized properly after reloading data

    Consider the following scenario:

    1. The paging view controller gets loaded with some data.
    2. The data changes (including the number of pages/paging items) .
    3. So, we call reloadData on the paging view controller.

    Everything gets reloaded, the number of paging items get updated but they are not sized correctly. My guess is that the function that specifies widthForPagingItem does not get recalled after reload.

    The only solution is to completely remove and re-add the view controller which is not ok at all.

    Thank you.

    opened by rptoma 11
  • How can I hide the menu? (SwiftUI)

    How can I hide the menu? (SwiftUI)

    I am trying to hide the menu, and with little luck, cannot find any options other than the menuHeight, however, this is a computed property which provides the error below.

    private var pagingOptions: PagingOptions {
        let options = PagingOptions()
        options.menuHeight = 0 <-- Error here
    
        return options
    }
    
    PageView(options: pagingOptions, items: items, selectedIndex: $selectedIndex) { item in
    //
    }
    

    Error: "Cannot assign to property: 'menuHeight' is a get-only property"

    How can I completely hide the menu?

    opened by trevordevelops 0
  • How To Lazy Load Page

    How To Lazy Load Page

    I've got three pages, and when I set the default to select the second one, I don't want viewDidLoad on the first and third page to be called, it's initialized the first time I visit the corresponding page, what do I do

    opened by rainedAllNight 0
  • There is an issue that accidentally gets stuck and cannot keep clicking other tab item

    There is an issue that accidentally gets stuck and cannot keep clicking other tab item

    I print some log, Looking forward to your reply: $$$$$: 01 didSelectItem pagingItem = DuPagingTitleIndexItem(index: 13, title: "skateboard"), state = selected(pagingItem: DUCommunity.DuPagingTitleIndexItem(index: 12, title: "Exercise and fitness"))

    $$$$$ 02 select pagingItem = DuPagingTitleIndexItem(index: 13, title: "skateboard"), direction = forward(sibling: true), animated = true

    $$$$$ 03-1 selectNext animated = true this step call selectNext(:), and goon calling scrollForward(), There is no print next “$$$$$: 04 willScrollToItem state = ...”, It's to say that be not calling setContentOffset when "call scrollForward", the state == .scrolling cannot be changed, And then click anyway, right,slect(index:) come into "defult: break" func selectNext(animated: Bool) { if animated { resetState() delegate?.scrollForward() } else { ... } } and then call scrollForward() func scrollForward() { if isRightToLeft { switch manager.state { case .first, .center: setContentOffset(.zero, animated: true) case .single, .empty, .last: break } } else { switch manager.state { case .first: setContentOffset(pageSize, animated: true) case .center: setContentOffset(pageSize * 2, animated: true) case .single, .empty, .last: break } } }

    opened by zllarry 0
  • Issue on Index

    Issue on Index

    Hi, I have a problem when shifting tabs when I swipe right (next tab) and swipe left (previous tab) it doesn't get an accurate index accordingly Any solution / answer would be appreciated Thank you

    Example: Current Position: 5, Swipe Left: 2, Swipe Right: 3

    Here's my code: `func numberOfViewControllers(in pagingViewController: Parchment.PagingViewController) -> Int { return categoryMenuLevelOneTitle.count }

    func pagingViewController(_: Parchment.PagingViewController, viewControllerAt index: Int) -> UIViewController {
        return NewCategoryLevelTwoViewController(index: index, content: categoryMenuLevelTwoTitle)
    }
    
    func pagingViewController(_: Parchment.PagingViewController, pagingItemAt index: Int) -> Parchment.PagingItem {
        return PagingIndexItem(index: index, title: categoryMenuLevelOneTitle[index])
    }`
    
    opened by ignatiojulian 0
  • PageView does not work in ScrollView

    PageView does not work in ScrollView

    I am using version 3.1.0. In swiftui, Pageview does not work when you put it in ScrollView. Probably it is related to nested scrollviews issue. It works when you set frame but the content of the pageview will be dynamic. Is there any trick to solve that issue ?

    ScrollView {
          PageView(options: getOptions(), items: items, selectedIndex: $selectedIndex) { item in
               VStack {
                       ForEach(0..<100) { i in
                            Text("\(i)")
                       }
                   }
                }
    }
    
    opened by canozt 2
  • The menu items label is not showing

    The menu items label is not showing

    import UIKit import Parchment

    class InverterSmartVC: BaseVC {

    // MARK: - Variables private var viewModel: InverterSmartVM?

    var viewController: [UIViewController] = []
    
    let titles: [String] = ["SmartSettingVC",
                            "ReservePowerSettingVC",
                            "AlarmSettingVC",
                            "SwitchSettingVC"
                            ]
    var pagingViewController = PagingViewController()
    

    // MARK: - IBOutlets @IBOutlet weak var navBar: CustomNavBar! @IBOutlet weak var containerView: UIView!

    // MARK: - View Life Cycle override func viewDidLoad() { super.viewDidLoad() self.initialSetup() self.setupHeaderView() self.setupPagingController() self.setupMenu() self.setupColors() self.setupFonts() }

    }

    // MARK: - Extension Private Functions extension InverterSmartVC {

    private func initialSetup() {
        self.viewController = [
            createSmartSetting(), createSmartSetting(), createSmartSetting(), createSmartSetting()
        ]
    }
    
    private func setupHeaderView() {
        self.navBar.titleText = "SMSYNG 1150"
        self.navBar.subtitleText = "Bathroom"
        self.navBar.tapCallBack = { [weak self] success in
            if success {
                AppRouter.shared.popController(from: self?.tabBarController)
            } else {
            //            present info
            }
        }
    }
    
    private func setupPagingController() {
        self.pagingViewController.dataSource = self
        self.pagingViewController.select(index: 0)
        self.pagingViewController = PagingViewController(viewControllers: self.viewController)
        self.containerView.addSubview(pagingViewController.view)
        self.containerView.constrainToEdges(pagingViewController.view)
        self.pagingViewController.didMove(toParent: self)
        self.pagingViewController.reloadData()
    }
    
    private func setupMenu() {
        self.pagingViewController.indicatorOptions = .visible(height: 2, zIndex: Int.max, spacing: UIEdgeInsets.zero, insets: UIEdgeInsets(top: 0, left: 10, bottom: 0, right: 10))
        self.pagingViewController.borderOptions = .hidden
    }
    
    private func setupColors() {
        self.pagingViewController.indicatorColor = AppColors.titleColor
        self.pagingViewController.borderColor = AppColors.titleColor
        self.pagingViewController.backgroundColor = .clear
        self.pagingViewController.menuBackgroundColor = .clear
        self.pagingViewController.textColor = AppColors.darkRed
        self.pagingViewController.selectedTextColor = AppColors.titleColor
    }
    
    private func setupFonts() {
        self.pagingViewController.font = AppFonts.Soleto_Regular.withSize(14.0)
        self.pagingViewController.selectedFont = AppFonts.Soleto_Medium.withSize(14.0)
    }
    
    func createSmartSetting() -> UIViewController {
        AppRouter.shared.getSmartSettingVC()
    }
    

    }

    extension InverterSmartVC: PagingViewControllerDataSource {

    func numberOfViewControllers(in pagingViewController: PagingViewController) -> Int {
        return self.viewController.count
    }
    
    func pagingViewController(_ pagingViewController: PagingViewController, viewControllerAt index: Int) -> UIViewController {
        return self.viewController[index]
    }
    
    func pagingViewController(_: PagingViewController, pagingItemAt index: Int) -> PagingItem {
        return PagingIndexItem(index: index, title: self.titles[index])
    }
    

    }

    opened by RehanMuqeem 0
Releases(v3.2.0)
  • v3.2.0(Jan 23, 2022)

    Fixes

    • Fix issue with menu insets not updating #619
    • Update content size after parent size #623
    • Fix SPM linker settings #622 #615
    • Update Pods file to support iOS >= 9 #620
    Source code(tar.gz)
    Source code(zip)
  • v3.1.0(Oct 16, 2021)

    Added

    • Add support for pagingContentBackgroundColor property #592
    • Add contentInteraction property into PagingOptions #593

    Changes

    • Support for Xcode 13 #581 #601
    • Updated API for SwiftUI wrapper #572 #551
    • Drop support for iOS 8 #568
    • Remove support for older Swift versions #595
    • Improve accessibility of default paging cell #602

    Fixes

    • Remove Carthage reference in FRAMEWORK_SEARCH_PATH #569
    • Fix wrong page direction when current paging item is out of view #567
    • Fix issue with rotation when using SwiftUI wrapper #596
    Source code(tar.gz)
    Source code(zip)
  • v3.0.1(Dec 15, 2020)

  • v3.0.0(Dec 3, 2020)

    Changes:

    • Custom PageViewController (#468)
    • RTL language support (#468)

    This version introduces some breaking changes:

    Replaced EMPageViewController

    EMPageViewController has been replaced with our own PageViewController implementation, which fixes a bunch of issues (#524, #527, #426). The API of the new page view controller is pretty much identical to the old one, but the names of the types have changed:

    open class PagingViewController:
       UIViewController,
       UICollectionViewDelegate,
    -  EMPageViewControllerDataSource,
    -  EMPageViewControllerDelegate {
    +  PageViewControllerDataSource,
    +  PageViewControllerDelegate {
       
    -  public let pageViewController: EMPageViewController
    +  public let pageViewController: PageViewController
        
    -  open func em_pageViewController(_ pageViewController: EMPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
    +  open func pageViewController(_ pageViewController: PageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
        
    -  open func em_pageViewController(_ pageViewController: EMPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
    +  open func pageViewController(_ pageViewController: PageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
    
    -  open func em_pageViewController(_ pageViewController: EMPageViewController, isScrollingFrom startingViewController: UIViewController, destinationViewController: UIViewController?, progress: CGFloat) {
    +  public func pageViewController(_ pageViewController: PageViewController, isScrollingFrom startingViewController: UIViewController, destinationViewController: UIViewController?, progress: CGFloat) {
        
    -  open func em_pageViewController(_ pageViewController: EMPageViewController, willStartScrollingFrom startingViewController: UIViewController, destinationViewController: UIViewController) {
    +  public func pageViewController(_ pageViewController: PageViewController, willStartScrollingFrom startingViewController: UIViewController, destinationViewController: UIViewController) {
    
    -  open func em_pageViewController(_ pageViewController: EMPageViewController, didFinishScrollingFrom startingViewController: UIViewController?, destinationViewController: UIViewController, transitionSuccessful: Bool) {
    +  open func pageViewController(_ pageViewController: PageViewController, didFinishScrollingFrom startingViewController: UIViewController, destinationViewController: UIViewController, transitionSuccessful: Bool) {
    }
    

    More details about the release can be found here: #452

    Source code(tar.gz)
    Source code(zip)
  • v3.0.0-beta2(Sep 28, 2020)

  • v3.0.0-beta(Sep 2, 2020)

  • v2.4.0(Jun 1, 2020)

    • Fix PagingTitleCell label horizontal constraints (#480)
    • Fix regression causing menuInteraction property not to work properly (#486)
    • Reload data when updating paging items in SwiftUI (#470)
    Source code(tar.gz)
    Source code(zip)
  • v2.3.0(Apr 2, 2020)

    • Add support for SwiftUI (#460)
    • Add support for self-sizing menu cells (#461)
    • Handle menu background color change after viewDidLoad (#465)
    Source code(tar.gz)
    Source code(zip)
  • v2.2.0(Mar 21, 2020)

  • v2.1.0(Mar 11, 2020)

    • Add option to position menu vertically (#412)
    • Combine all example targets into single target (#442)
    • Fix missing import causing SwiftPM to fail (#420)
    • Fix memory leak occurring when configuring size cache (#433)
    • Fix issue with initial selection not being set (#438)
    • Fix regression causing indicator not to animate (#441)
    • Fix issues with invalidation of size cache (#444)
    Source code(tar.gz)
    Source code(zip)
  • v2.0.1(Feb 8, 2020)

  • v2.0.0(Feb 8, 2020)

    This version introduces a couple of breaking changes that are outlined below. If you're having issues upgrading or you see other breaking changes that are not outlined below, please let us know. More details about the release can be found here: #243.

    Removed FixedPagingViewController

    FixedPagingViewController has been removed. You can now initialize PagingViewController directly with an array of view controllers.

    -FixedPagingViewController(viewControllers: viewControllers)
    +PagingViewController(viewControllers: viewControllers)
    

    Removed generics (#285)

    PagingViewController is not longer generic on the PagingItem type. This means that all places where you previously had to specify the generic type, or cast to generic type, can be removed.

    -PagingViewController<CalendarItem>()
    +PagingViewController()
    
    -func pagingViewController<T>(_ pagingViewController: PagingViewController<T>, pagingItemForIndex index: Int) -> T {
    -  return PagingIndexItem(index: index, title: cities[index]) as! T
    -}
    +func pagingViewController(_: PagingViewController, pagingItemAt index: Int) -> PagingItem {
    +  return PagingIndexItem(index: index, title: cities[index])
    +}
    

    Moved size delegate into separate protocol

    The widthForPagingItem delegate method have been moved out of the PagingViewControllerDelegate and into a separate protocol called PagingViewControllerSizeDelegate. You now need to set the sizeDelegate property on PagingViewController:

    -pagingViewController.delegate = self
    +pagingViewController.sizeDelegate = self
    

    Replaced menuItemSource with register(cellClass:)

    The menuItemSource property for customizing the cell type has been removed. Instead you can customize the cell type for a given PagingItem by using register(cellClass:) and register(nib:). The benefit of this approach is that we can support multiple cell types in the same menu (#390).

    - pagingViewController.menuItemSource = .class(type: CalendarPagingCell.self)
    + pagingViewController.register(CalendarPagingCell.self, for: CalendarItem.self)
    

    Updated naming of data sources

    As well as removing generics from the data sources, the naming has also been updated to be a bit more Swift-y.

    protocol PagingViewControllerDataSource: class {
    -  func numberOfViewControllers<T>(in pagingViewController: PagingViewController<T>) -> Int
    +  func numberOfViewControllers(in pagingViewController: PagingViewController) -> Int
    -  func pagingViewController<T>(_ pagingViewController: PagingViewController<T>, viewControllerForIndex index: Int) -> UIViewController
    +  func pagingViewController(_: PagingViewController, viewControllerAt index: Int) -> UIViewController
    - func pagingViewController<T>(_ pagingViewController: PagingViewController<T>, pagingItemForIndex index: Int) -> T
    +  func pagingViewController(_: PagingViewController, pagingItemAt index: Int) -> PagingItem
    }
    
    protocol PagingViewControllerInfiniteDataSource: class {
    -  func pagingViewController<T>(_ pagingViewController: PagingViewController<T>, viewControllerForPagingItem: T) -> UIViewController
    +  func pagingViewController(_: PagingViewController, viewControllerFor pagingItem: PagingItem) -> UIViewController
    -  func pagingViewController<T>(_ pagingViewController: PagingViewController<T>, pagingItemBeforePagingItem: T) -> T?
    +  func pagingViewController(_: PagingViewController, itemBefore pagingItem: PagingItem) -> PagingItem?
    -  func pagingViewController<T>(_ pagingViewController: PagingViewController<T>, pagingItemAfterPagingItem: T) -> T?
    +  func pagingViewController(_ : PagingViewController, itemAfter pagingItem: PagingItem) -> PagingItem?
    }
    
    Source code(tar.gz)
    Source code(zip)
  • v2.0.0-beta(Nov 17, 2019)

    Please help test this release and let us know if you find any issues! This version introduces a couple of breaking changes that are outlined below. If you're having issues upgrading or you see other breaking changes that are not outlined below, please let us know. More details about the release can be found here: #243.

    Removed FixedPagingViewController

    FixedPagingViewController has been removed. You can now initialize PagingViewController directly with an array of view controllers.

    -FixedPagingViewController(viewControllers: viewControllers)
    +PagingViewController(viewControllers: viewControllers)
    

    Removed generics (#285)

    PagingViewController is not longer generic on the PagingItem type. This means that all places where you previously had to specify the generic type, or cast to generic type, can be removed.

    -PagingViewController<CalendarItem>()
    +PagingViewController()
    
    -func pagingViewController<T>(_ pagingViewController: PagingViewController<T>, pagingItemForIndex index: Int) -> T {
    -  return PagingIndexItem(index: index, title: cities[index]) as! T
    -}
    +func pagingViewController(_: PagingViewController, pagingItemAt index: Int) -> PagingItem {
    +  return PagingIndexItem(index: index, title: cities[index])
    +}
    

    Moved size delegate into separate protocol

    The widthForPagingItem delegate method have been moved out of the PagingViewControllerDelegate and into a separate protocol called PagingViewControllerSizeDelegate. You now need to set the sizeDelegate property on PagingViewController:

    -pagingViewController.delegate = self
    +pagingViewController.sizeDelegate = self
    

    Replaced menuItemSource with register(cellClass:)

    The menuItemSource property for customizing the cell type has been removed. Instead you can customize the cell type for a given PagingItem by using register(cellClass:) and register(nib:). The benefit of this approach is that we can support multiple cell types in the same menu (#390).

    - pagingViewController.menuItemSource = .class(type: CalendarPagingCell.self)
    + pagingViewController.register(CalendarPagingCell.self, for: CalendarItem.self)
    

    Updated naming of data sources

    As well as removing generics from the data sources, the naming has also been updated to be a bit more Swift-y.

    protocol PagingViewControllerDataSource: class {
    -  func numberOfViewControllers<T>(in pagingViewController: PagingViewController<T>) -> Int
    +  func numberOfViewControllers(in pagingViewController: PagingViewController) -> Int
    -  func pagingViewController<T>(_ pagingViewController: PagingViewController<T>, viewControllerForIndex index: Int) -> UIViewController
    +  func pagingViewController(_: PagingViewController, viewControllerAt index: Int) -> UIViewController
    - func pagingViewController<T>(_ pagingViewController: PagingViewController<T>, pagingItemForIndex index: Int) -> T
    +  func pagingViewController(_: PagingViewController, pagingItemAt index: Int) -> PagingItem
    }
    
    protocol PagingViewControllerInfiniteDataSource: class {
    -  func pagingViewController<T>(_ pagingViewController: PagingViewController<T>, viewControllerForPagingItem: T) -> UIViewController
    +  func pagingViewController(_: PagingViewController, viewControllerFor pagingItem: PagingItem) -> UIViewController
    -  func pagingViewController<T>(_ pagingViewController: PagingViewController<T>, pagingItemBeforePagingItem: T) -> T?
    +  func pagingViewController(_: PagingViewController, itemBefore pagingItem: PagingItem) -> PagingItem?
    -  func pagingViewController<T>(_ pagingViewController: PagingViewController<T>, pagingItemAfterPagingItem: T) -> T?
    +  func pagingViewController(_ : PagingViewController, itemAfter pagingItem: PagingItem) -> PagingItem?
    }
    
    Source code(tar.gz)
    Source code(zip)
  • v1.7.0(Sep 26, 2019)

    • Update to Swift 5 and Xcode 10.2 #339
    • Fix issue changing selection when view is not visible #371
    • Fix unbalanced appearance transitions #373
    • Fix issues when compiled as SPM dependency (Xcode 11) (#386)
    • Add support for Accio as dependency manager #345
    Source code(tar.gz)
    Source code(zip)
  • v1.6.0(Mar 3, 2019)

    • Forward appearance methods from EMPageViewController #306
    • Fix indicator insets with only one item #307
    • Add method for reloading menu #312
    Source code(tar.gz)
    Source code(zip)
  • v1.5.0(Nov 18, 2018)

    • Include vertical insets for indicator view #271
    • Remove development team from Parchment target #280
    • Update indicator and border views when changing options #245
    • Fix issue with width delegate not being called #244
    • Fix issue with invalidating collection view layout #240
    Source code(tar.gz)
    Source code(zip)
  • v1.4.1(Aug 15, 2018)

  • v1.4.0(Aug 11, 2018)

  • v1.3.0(May 19, 2018)

    • Add version checks to support Swift >=3.2 #190, #184
    • Fix issue with indicator/border class was not registered #191
    • Fix issue with reloading data when view controllers did not change #201
    Source code(tar.gz)
    Source code(zip)
  • v1.2.0(Apr 15, 2018)

    • Upgrade to Swift 4.1 #171 (thanks @voyager163!)
    • Prevent unnecessary view controller initializations #160
    • Fix issues with reloading data #157
    • Fix issue with clearing all items in page view controller (a5759ba)
    • Fix issue where willScrollToItem delegate was not called #173
    • Fix layout bug with cell heights when using width delegate #155
    Source code(tar.gz)
    Source code(zip)
  • v1.1.0(Mar 25, 2018)

    • Add method for reloading data without passing initial item (8ebd931)
    • Add option for selected font #143 (thanks @cheebow!)
    • Fix issue with reloading data when using PagingViewControllerDataSource (07641e2)
    • Fix integer overflow causing crash in UnplashExample #140
    Source code(tar.gz)
    Source code(zip)
  • v1.0.3(Mar 1, 2018)

  • v1.0.2(Feb 22, 2018)

  • v1.0.1(Feb 3, 2018)

    • Fix issue with selecting items programatically #125
    • Fix wrong color on collection view background #126
    • Fix issue with menu items being clipped #127
    Source code(tar.gz)
    Source code(zip)
  • v1.0.0(Jan 29, 2018)

    This release introduces a lot of breaking changes, a bunch of new features and a couple of bug fixes. Here are the most notable changes, with a full list of changes below:

    Removed PagingOptions initializer #98

    All configuration is now moved into properties on the PagingViewController class. You no longer have to initialize a PagingViewController with an instance conforming to the PagingOptions protocol. This reduces the boilerplate of having to create a separate options struct when you just need to override a single value. It also means you can change the options after the PagingViewController has been initialized. All the properties on the PagingTheme protocol has also moved into separate properties on PagingViewController.

    Before:

    struct Theme: PagingTheme {
      let textColor: UIColor = .red
    }
    
    struct Options: PagingOptions {
      let theme: PagingTheme = Theme()
      let menuItemSize: PagingMenuItemSize = .fixed(width: 100, height: 40)
    }
    
    let pagingViewController = PagingViewController(options: Options())
    

    After:

    let pagingViewController = PagingViewController()
    pagingViewController.menuItemSize = .fixed(width: 100, height: 40)
    pagingViewController.textColor = .red
    

    Renamed data source #99

    The current data source protocol has been renamed to PagingViewControllerInfiniteDataSource and moved into the property called infiniteDataSource.

    Added new data source #99

    A new PagingViewControllerDataSource protocol has been added that makes it easier to set up a custom data source if you have a fixed number of view controllers. To use the new data source, you only need to return the total number of view controllers as well as the view controller and PagingItem for a given index. The new data source replaces the existing dataSource property.

    Example:

    extension ViewController: PagingViewControllerDataSource {
    
      func numberOfViewControllers<T>(in: PagingViewController<T>) -> Int {
        return items.count
      }  
    
      func pagingViewController<T>(_ pagingViewController: PagingViewController<T>, viewControllerForIndex index: Int) -> UIViewController {
        return ItemViewController(item: items[index])
      }
    
      func pagingViewController<T>(_ pagingViewController: PagingViewController<T>, pagingItemForIndex index: Int) -> T {
        return items[index] as! T
      }
    }
    
    ...
    
    pagingViewController.dataSource = self
    

    Updated delegate protocol #100

    Three new delegate methods have been added to the PagingViewControllerDelegate protocol. You can now be notified before, during and after the user navigates to another view controller:

    protocol PagingViewControllerDelegate: class {
    
      func pagingViewController<T>(
        _ pagingViewController: PagingViewController<T>,
        isScrollingFromItem currentPagingItem: T,
        toItem upcomingPagingItem: T?,
        startingViewController: UIViewController,
        destinationViewController: UIViewController?,
        progress: CGFloat)
    
      func pagingViewController<T>(
        _ pagingViewController: PagingViewController<T>,
        willScrollToItem pagingItem: T,
        startingViewController: UIViewController,
        destinationViewController: UIViewController)
    
      func pagingViewController<T>(
        _ pagingViewController: PagingViewController<T>,
        didScrollToItem pagingItem: T,
        startingViewController: UIViewController?,
        destinationViewController: UIViewController,
        transitionSuccessful: Bool)
    
      func pagingViewController<T>(
        _ pagingViewController: PagingViewController<T>,
        widthForPagingItem pagingItem: T,
        isSelected: Bool) -> CGFloat?
    }
    

    The widthForPagingItem: delegate has been changed to return CGFloat? instead of CGFloat (See: #100). The default implementation will return nil.

    Removed FixedPagingViewControllerDelegate protocol #100

    The FixedPagingViewControllerDelegate protocol is replaced by the PagingViewControllerDelegate protocol. The new delegate does not include the index for the paging items, but you can get the current index from the PagingIndexItem like this:

    extension ViewController: PagingViewControllerDelegate {
      func pagingViewController<T>(_ pagingViewController: PagingViewController<T>, didScrollToItem pagingItem: T, startingViewController: UIViewController?, destinationViewController: UIViewController, transitionSuccessful: Bool) {
        if let indexItem = pagingItem as? PagingIndexItem {
          print("index: ", indexItem.index)
        }
      }
    }
    

    Added

    • Add option to always center selected menu item #101
    • Allow subclassing the collection view layout #104
    • Add empty implementations of collection view delegate methods (4840483)
    • Add option to disable content interaction #113
    • Add option for selected background color #114
    • Add method for selecting paging items based on index #117

    Changed

    • Rename selectPagingItem to select(pagingItem:) #105
    • Make PagingState property public #107
    • Make PagingItems struct public #108
    • Make PagingState extension properties public (f842a7b)
    • Make indicator layout attributes open to allow subclassing (7c35acc)
    • Change collection view delegate methods to open (68b125b)
    • Replace PagingTheme with PagingOptions #111
    • Rename headerBackgroundColor to menuBackgroundColor #116

    Fixes

    • Fix performance issue with updating content offset #106
    • Set background color for paging cell based on options (1a70bd6)
    • Fix layout calculation when using transforms #102
    • Account for menu spacing when generating items #103
    • Fix bug with animation when selecting items (73913f)
    Source code(tar.gz)
    Source code(zip)
  • v0.9.0(Dec 25, 2017)

  • v0.8.0(Nov 19, 2017)

  • v0.7.0(Nov 7, 2017)

    • Change access for EMPageViewController delegate method #72
    • Improve performance by using manual frames for menu cells #68
    • Add option to customize indicator and border view #67
    • Update documentation #60
    Source code(tar.gz)
    Source code(zip)
  • v0.6.0(Sep 25, 2017)

  • v0.5.0(Aug 22, 2017)

    Add support for scrolling in header #48

    • Require PagingItem to conform to Hashable and Comparable: fbd7aff
    • Write custom collection view layout instead of using UICollectionViewFlowLayout c6f78b4

    Note: With this change, Parchment requires PagingItem to conform to both Hashable and Comparable. This means any existing PagingItem implementation have to be updated.

    Source code(tar.gz)
    Source code(zip)
Owner
Martin Rechsteiner
Lead iOS developer at DNB
Martin Rechsteiner
SwiftySideMenu is a lightweight and easy to use side menu controller to add left menu and center view controllers with scale animation based on Pop framework.

SwiftySideMenu SwiftySideMenu is a lightweight, fully customizable, and easy to use controller to add left menu and center view controllers with scale

Hossam Ghareeb 84 Feb 4, 2022
A fully customizable container view controller to display a set of ViewControllers in a horizontal scroll view. Written in Swift.

DTPagerController This is a control for iOS written in Swift. DTPagerController is simple to use and easy to customize. Screenshots Default segmented

Tung Vo 290 Nov 13, 2022
A side menu controller written in Swift for iOS

Description SideMenuController is a custom container view controller written in Swift which will display the main content within a center panel and th

Teo 1.2k Dec 29, 2022
Menu controller with expandable item groups, custom position and appearance animation written with Swift. Similar to ActionSheet style of UIAlertController.

Easy to implement controller with expanding menu items. Design is very similar to iOS native ActionSheet presentation style of a UIAlertController. As

Anatoliy Voropay 22 Dec 27, 2022
iOS Slide Menu Controller. It is written in pure swift.

SlideMenuController Requirements iOS 9+ Installation SlideMenuController is available through CocoaPods. To install it, simply add the following line

Myung gi son 40 Jan 16, 2022
A Slide Menu, written in Swift, inspired by Slide Menu Material Design

Swift-Slide-Menu (Material Design Inspired) A Slide Menu, written in Swift 2, inspired by Navigation Drawer on Material Design (inspired by Google Mat

Boisney Philippe 90 Oct 17, 2020
Slide-Menu - A Simple Slide Menu With Swift

Slide Menu!! Весь интерфейс создан через код

Kirill 0 Jan 8, 2022
EasyMenu - SwiftUI Menu but not only button (similar to the native Menu)

EasyMenu SwiftUI Menu but not only button (similar to the native Menu) You can c

null 10 Oct 7, 2022
Swift-sidebar-menu-example - Create amazing sidebar menu with animation using swift

 SWIFT SIDEBAR MENU EXAMPLE In this project I create a awesome side bar menu fo

Paolo Prodossimo Lopes 4 Jul 25, 2022
Hamburger Menu Button - A hamburger menu button with full customization

Hamburger Menu Button A hamburger menu button with full customization. Inspired by VinhLe's idea on the Dribble How to use it You can config the looks

Toan Nguyen 114 Jun 12, 2022
XLPagerTabStrip is a Container View Controller that allows us to switch easily among a collection of view controllers

XLPagerTabStrip is a Container View Controller that allows us to switch easily among a collection of view controllers. Pan gesture can be used to move on to next or previous view controller. It shows a interactive indicator of the current, previous, next child view controllers.

xmartlabs 6.8k Dec 27, 2022
PagingKit provides customizable menu UI. It has more flexible layout and design than the other libraries.

PagingKit provides customizable menu & content UI. It has more flexible layout and design than the other libraries. What's this? There are many librar

Kazuhiro Hayashi 1.3k Jan 9, 2023
A fully customizable popup style menu for iOS 😎

Guide Check out the documentation and guides for details on how to use. (Available languages:) English 简体中文 What's a better way to know what PopMenu o

Cali Castle 1.5k Dec 30, 2022
🔻 Dropdown Menu for iOS with many customizable parameters to suit any needs

MKDropdownMenu Dropdown Menu for iOS with many customizable parameters to suit any needs. Inspired by UIPickerView. Installation CocoaPods MKDropdownM

Max Konovalov 531 Dec 26, 2022
Animated side menu with customizable UI

Side Menu Animated side menu with customizable UI. Made in Yalantis. Check this project on dribbble. Check this project on Behance. Requirements iOS 7

Yalantis 2.7k Dec 27, 2022
A simple customizable side menu written in SwiftUI.

NSideMenu Description A simple customizable side menu written in SwiftUI. Give a Star! ⭐ Feel free to request an issue on github if you find bugs or r

null 5 Oct 10, 2022
Drawer view controller that easy to use!

KWDrawerController Drawer view controller that is easy to use! Installation CocoaPods (iOS 8+ projects) KWDrawerController is available on CocoaPods.

Jungwon An 157 Jun 14, 2022
Drawer view controller that easy to use!

KWDrawerController Drawer view controller that is easy to use! Installation CocoaPods (iOS 8+ projects) KWDrawerController is available on CocoaPods.

Jungwon An 157 Jun 14, 2022
iOS Slide Menu View based on Google+, iQON, Feedly, Ameba iOS app. It is written in pure swift.

SlideMenuControllerSwift iOS Slide View based on iQON, Feedly, Google+, Ameba iPhone app. Installation CocoaPods pod 'SlideMenuControllerSwift' Carth

Yuji Hato 3.3k Dec 29, 2022