• Stars
    star
    6,880
  • Rank 5,716 (Top 0.2 %)
  • Language
    Swift
  • License
    MIT License
  • Created about 10 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Android PagerTabStrip for iOS.

XLPagerTabStripView

Build status Platform iOS Swift 5 compatible Carthage compatible CocoaPods compatible License: MIT

Made with ❀️ by XMARTLABS.

Android PagerTabStrip for iOS!

πŸ‘‰ Looking for a SwiftUI version? Check out PagerTabStripView, it's fully written in pure SwiftUI. πŸ‘ˆ

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.

Getting involved

  • If you want to contribute please feel free to submit pull requests.
  • If you have a feature request please open an issue.
  • If you found a bug or need help please check older issues, FAQ and threads on StackOverflow (Tag 'XLPagerTabStrip') before submitting an issue.

Before contribute check the CONTRIBUTING file for more info.

If you use XLPagerTabStrip in your app we would love to hear about it! Drop us a line on twitter.

Pager Types

The library provides 4 different ways to show the view controllers.

Button Bar

This is likely the most common pager type. It's used by many well-known apps such as instagram, youtube, skype, and many others.

Bar

This mode doesn't show a title neither an image. It only shows a bar that indicates the current view controller.

Twitter

A long time ago, the twitter app made use of this type of pager in the app main screen.

Segmented

This mode uses a UISegmentedControl to indicate which view controller is being displayed.

Usage

Basically, we just need to provide the list of child view controllers to show, and these view controllers should provide the information (title or image) that will be shown in the associated indicator.

Let's see the steps to do this:

Choose which type of pager we want to create

First, we must choose the type of pager we want to create. Depending on our choice, we will have to create a view controller that extends from one of the following controllers: TwitterPagerTabStripViewController, ButtonBarPagerTabStripViewController, SegmentedPagerTabStripViewController, BarPagerTabStripViewController.

All these built-in pager controllers extend from the base class PagerTabStripViewController. You can also make your custom pager controller by extending directly from PagerTabStripViewController in the event that no pager menu type fits your needs.

import XLPagerTabStrip

class MyPagerTabStripName: ButtonBarPagerTabStripViewController {
  ..
}
Connect outlets and add layout constraints

We strongly recommend using IB to set up our page controller views.

Drag a UIViewController into the storyboard and set up its class with your pager controller (MyPagerTabStripName). Drag a UIScrollView into your view controller view and connect PagerTabStripViewController containerView outlet with the scroll view.

Depending on which type of paging view controller you are working with you may have to connect more outlets.

For BarPagerTabStripViewController, we should connect barView outlet. barView type is UIView. ButtonBarPagerTabStripViewController requires us to connect buttonBarView outlet. buttonBarView type is ButtonBarView which extends from UICollectionView. SegmentedPagerTabStripViewController has a segmentedControl outlet; if the outlet is not connected the library try to set up the navigationItem titleView property using a UISegmentedControl. TwitterPagerTabStripViewController doesn't require us to connect any additional outlet.

The example project contains a example for each pager controller type and we can look into it to see how views were added and how outlets were connected.

Provide the view controllers that will appear embedded into the PagerTabStrip view controller

You can provide the view controllers by overriding func viewControllers(for: pagerTabStripController: PagerTabStripViewController) -> [UIViewController] method.

override public func viewControllers(for pagerTabStripController: PagerTabStripViewController) -> [UIViewController] {
  return [MyEmbeddedViewController(), MySecondEmbeddedViewController()]
}

The method above is the only method declared in PagerTabStripDataSource protocol. We don't need to explicitly conform to it since base pager class already does it.

Provide information to show in each indicator

Every UIViewController that will appear within the PagerTabStrip needs to provide either a title or an image. In order to do so they should conform to IndicatorInfoProvider by implementing func indicatorInfo(for pagerTabStripController: PagerTabStripViewController) -> IndicatorInfo which provides the information required to show the PagerTabStrip menu (indicator) associated with the view controller.

class MyEmbeddedViewController: UITableViewController, IndicatorInfoProvider {

  func indicatorInfo(for pagerTabStripController: PagerTabStripViewController) -> IndicatorInfo {
    return IndicatorInfo(title: "My Child title")
  }
}

For a detailed step-by-step guide about how to use the library, please check out this community blog post.

That's it! We're done! 🍻🍻

Customization

Pager Behaviour

The pager indicator can be updated progressive as we swipe or at once in the middle of the transition between the view controllers. By setting up pagerBehaviour property we can choose how the indicator should be updated.

public var pagerBehaviour: PagerTabStripBehaviour
public enum PagerTabStripBehaviour {
    case common(skipIntermediteViewControllers: Bool)
    case progressive(skipIntermediteViewControllers: Bool, elasticIndicatorLimit: Bool)
}

Default Values:

// Twitter Type
PagerTabStripBehaviour.common(skipIntermediateViewControllers: true)
// Segmented Type
PagerTabStripBehaviour.common(skipIntermediateViewControllers: true)
// Bar Type
PagerTabStripBehaviour.progressive(skipIntermediateViewControllers: true, elasticIndicatorLimit: true)
// ButtonBar Type
PagerTabStripBehaviour.progressive(skipIntermediateViewControllers: true, elasticIndicatorLimit: true)

As you might have noticed, common and progressive enumeration cases have skipIntermediateViewControllers and elasticIndicatorLimit associated values.

skipIntermediateViewControllers allows us to skip intermediate view controllers when a tab indicator is tapped.

elasticIndicatorLimit allows us to tension the indicator when we reach a limit, I mean when we try to move forward from last indicator or move back from first indicator.

PagerTabStripDelegate & PagerTabStripIsProgressiveDelegate

Normally we don't need to implement these protocols because each pager type already conforms to it in order to properly update its indicator. However, there may be some scenarios when overriding a method may come in handy.

public protocol PagerTabStripDelegate: class {

    func updateIndicator(for viewController: PagerTabStripViewController, fromIndex: Int, toIndex: Int)
}

public protocol PagerTabStripIsProgressiveDelegate : PagerTabStripDelegate {

    func updateIndicator(for viewController: PagerTabStripViewController, fromIndex: Int, toIndex: Int, withProgressPercentage progressPercentage: CGFloat, indexWasChanged: Bool)
}

Again, the method invoked by the library depends on the pagerBehaviour value.

ButtonBar Customization

settings.style.buttonBarBackgroundColor: UIColor?
// buttonBar minimumInteritemSpacing value, note that button bar extends from UICollectionView
settings.style.buttonBarMinimumInteritemSpacing: CGFloat?
// buttonBar minimumLineSpacing value
settings.style.buttonBarMinimumLineSpacing: CGFloat?
// buttonBar flow layout left content inset value
settings.style.buttonBarLeftContentInset: CGFloat?
// buttonBar flow layout right content inset value
settings.style.buttonBarRightContentInset: CGFloat?

// selected bar view is created programmatically so it's important to set up the following 2 properties properly
settings.style.selectedBarBackgroundColor = UIColor.black
settings.style.selectedBarHeight: CGFloat = 5

// each buttonBar item is a UICollectionView cell of type ButtonBarViewCell
settings.style.buttonBarItemBackgroundColor: UIColor?
settings.style.buttonBarItemFont = UIFont.systemFont(ofSize: 18)
// helps to determine the cell width, it represent the space before and after the title label
settings.style.buttonBarItemLeftRightMargin: CGFloat = 8
settings.style.buttonBarItemTitleColor: UIColor?
// in case the barView items do not fill the screen width this property stretch the cells to fill the screen
settings.style.buttonBarItemsShouldFillAvailableWidth = true
// only used if button bar is created programmatically and not using storyboards or nib files as recommended.
public var buttonBarHeight: CGFloat?

Important: Settings should be called before viewDidLoad is called.

override func viewDidLoad() {
   self.settings.style.selectedBarHeight = 2
   self.settings.style.selectedBarBackgroundColor = UIColor.white

   super.viewDidLoad()
}
Update cells when selected indicator changes

We may need to update the indicator cell when the displayed view controller changes. The following function properties help to accomplish that. Depending on our pager pagerBehaviour value we will have to set up changeCurrentIndex or changeCurrentIndexProgressive.

public var changeCurrentIndex: ((oldCell: ButtonBarViewCell?, newCell: ButtonBarViewCell?, animated: Bool) -> Void)?
public var changeCurrentIndexProgressive: ((oldCell: ButtonBarViewCell?, newCell: ButtonBarViewCell?, progressPercentage: CGFloat, changeCurrentIndex: Bool, animated: Bool) -> Void)?

Let's see an example:

changeCurrentIndexProgressive = { (oldCell: ButtonBarViewCell?, newCell: ButtonBarViewCell?, progressPercentage: CGFloat, changeCurrentIndex: Bool, animated: Bool) -> Void in
    guard changeCurrentIndex == true else { return }

    oldCell?.label.textColor = UIColor(white: 1, alpha: 0.6)
    newCell?.label.textColor = UIColor.white

    if animated {
        UIView.animate(withDuration: 0.1, animations: { () -> Void in
            newCell?.transform = CGAffineTransform(scaleX: 1.0, y: 1.0)
            oldCell?.transform = CGAffineTransform(scaleX: 0.8, y: 0.8)
        })
    }
    else {
        newCell?.transform = CGAffineTransform(scaleX: 1.0, y: 1.0)
        oldCell?.transform = CGAffineTransform(scaleX: 0.8, y: 0.8)
    }
}

Bar Type Customization

settings.style.barBackgroundColor: UIColor?
settings.style.selectedBarBackgroundColor: UIColor?
// barHeight is only set up when the bar is created programmatically and not using storyboards or xib files as recommended.
settings.style.barHeight: CGFloat = 5

Twitter Type Customization

settings.style.dotColor = UIColor(white: 1, alpha: 0.4)
settings.style.selectedDotColor = UIColor.white
settings.style.portraitTitleFont = UIFont.systemFont(ofSize: 18)
settings.style.landscapeTitleFont = UIFont.systemFont(ofSize: 15)
settings.style.titleColor = UIColor.white

Segmented Type Customization

settings.style.segmentedControlColor: UIColor?

Requirements

  • iOS 9.3+
  • Xcode 10.2+

Examples

Follow these 3 steps to run Example project: Clone XLPagerTabStrip repository, open XLPagerTabStrip workspace and run the Example project.

Installation

CocoaPods

CocoaPods is a dependency manager for Cocoa projects.

To install XLPagerTabStrip, simply add the following line to your Podfile:

pod 'XLPagerTabStrip', '~> 9.0'

Carthage

Carthage is a simple, decentralized dependency manager for Cocoa.

To install XLPagerTabStrip, simply add the following line to your Cartfile:

github "xmartlabs/XLPagerTabStrip" ~> 9.0

SPM

  • File > Swift Packages > Add Package Dependency
  • Add https://github.com/xmartlabs/XLPagerTabStrip.git
  • Select "Up to Next Major" with "9.0.0"

FAQ

How to change the visible child view controller programmatically

PagerTabStripViewController provides the following methods to programmatically change the visible child view controller:

func moveToViewController(at index: Int)
func moveToViewController(at index: Int, animated: Bool)
func moveTo(viewController: UIViewController)
func moveTo(viewController: UIViewController, animated: Bool)

How to migrate from Swift 2 to Swift 3

Check out our migration guide

Author

Change Log

This can be found in the CHANGELOG.md file.

More Repositories

1

Eureka

Elegant iOS form builder in Swift
Swift
11,705
star
2

XLForm

XLForm is the most flexible and powerful iOS library to create dynamic table-view forms. Fully compatible with Swift & Obj-C.
Objective-C
5,790
star
3

XLActionController

Fully customizable and extensible action sheet controller written in Swift
Swift
3,326
star
4

Bender

Easily craft fast Neural Networks on iOS! Use TensorFlow models. Metal under the hood.
Swift
1,795
star
5

PagerTabStripView

πŸš€ Elegant Pager View fully written in pure SwiftUI.
Swift
722
star
6

Xniffer

A swift network profiler built on top of URLSession.
Swift
502
star
7

XLRemoteImageView

UIImageView that shows a progress indicator while the image is loading from server. It makes use of AFNetworking. It looks like the Instagram loading indicator.
Objective-C
346
star
8

fountain

Android Kotlin paged endpoints made easy
Kotlin
169
star
9

XLData

Elegant and concise way to load and show data sets into table and collection view. It supports AFNetworking, Core Data and memory data stores.
Objective-C
165
star
10

XLSlidingContainer

XLSlidingContainer is a custom container controller that embeds two independent view controllers allowing to easily maximize any of them using gestures.
Swift
149
star
11

android-snapshot-publisher

Gradle plugin to deploy Android Snapshot Versions
Kotlin
145
star
12

Swift-Project-Template

Script to easily create an iOS project base code!
Swift
144
star
13

Swift-Framework-Template

Swift script to easily create Swift frameworks!
Swift
143
star
14

react-native-line

Line SDK wrapper for React Native πŸš€
TypeScript
119
star
15

Ecno

Ecno is a task state manager built on top of UserDefaults in pure Swift 4.
Swift
102
star
16

XLSwiftKit

Helpers and extensions for Swift
Swift
101
star
17

XLMediaZoom

UI controls to view an image or reproduce a video in fullscreen like Instagram does.
Swift
92
star
18

XLMailBoxContainer

Custom container view controller ala MailBox app.
Objective-C
90
star
19

gong

Xmartlabs' Android Base Project Template
Kotlin
89
star
20

cordova-plugin-market

Cordova Plugin that allows you to access native Marketplace app (aka Google Play, App Store) from your app
Java
87
star
21

stock

Dart package for Async Data Loading and Caching. Combine local (DB, cache) and network data simply and safely.
Dart
74
star
22

Opera

Protocol-Oriented Network abstraction layer written in Swift.
Swift
74
star
23

Ahoy

A lightweight swift library to build onboarding experiences.
Swift
52
star
24

bigbang

Android base project used by Xmartlabs team
Kotlin
50
star
25

MetalPerformanceShadersProxy

A proxy for MetalPerformanceShaders which takes to a stub on a simulator and to the real implementation on iOS devices.
Objective-C
45
star
26

Swift-Style-Guide

Swift language style guide & coding conventions followed by Xmartlabs.
44
star
27

RxSimpleNoSQL

Reactive extensions for SimpleNoSQL
Java
37
star
28

docker-jenkins-android

Jenkins docker image for Android development
36
star
29

docker-htpasswd

Docker image to create a htpasswd file
32
star
30

spoter-embeddings

Create embeddings from sign pose videos using Transformers
Python
30
star
31

TypedNavigation

A lightweight library to help you navigate in compose with well typed functions.
Kotlin
23
star
32

XLMapChat

A chat application running on Node.js, using Socket.IO, GMaps, and more...
JavaScript
22
star
33

flutter-template

Xmartlabs' Flutter Base Project
Dart
17
star
34

XLDataLoader

Objective-C
16
star
35

tf_tabular

Easily build TensorFlow models on tabular data
Python
16
star
36

dreamsnap

Real life through the eyes of an artist
CSS
15
star
37

bigbang-template

Android template used by Xmartlabs team
Kotlin
14
star
38

blog

Xmartlabs Blog
CSS
14
star
39

MLKitTest

Source code related to a blog post about ML Kit
Swift
13
star
40

benderthon

Set of utilities to work easier with Bender.
Python
13
star
41

XLiOSKit

Objective-C
13
star
42

python-template

Python
9
star
43

react-template-xmartlabs

This is an internal private project - aims to be at some point in the future our React base project
TypeScript
9
star
44

gpgpu-comparison

9
star
45

XmartRecyclerView

A smart, simple and fast RecyclerView library
Java
8
star
46

jared-landing

Landing page for Jared Bot.
HTML
8
star
47

Fastlane-CI-Files

Fastlane CI files
Ruby
8
star
48

fluttips

Flutter trips and tricks
JavaScript
8
star
49

Android-Style-Guide

Style guide for Android by Xmartlabs
7
star
50

XLMaterialCalendarView

MaterialCalendarView powered with reactive bindings and with the Java 8 Time API!
Java
6
star
51

rnx-cli

TypeScript
6
star
52

docker-android

Docker image for Android development.
6
star
53

gh-top-repos-users

Download the contributors of the top repos.
Python
5
star
54

BuildSlackNotifier

Jenkins plugin to send Android build results through a slack channel using incoming webhooks
Java
4
star
55

javascript-plugin

Source Code of blog Making a JS widget: a full-stack approach
Ruby
4
star
56

AndroidSwissKnife

Kotlin
3
star
57

projecthub-landing

ProjectHub lets you manage your GitHub Projects on the fly, from your mobile phone.
HTML
3
star
58

gh2s3

Download GitHub Archive data and upload it to an Amazon S3 bucket.
Python
3
star
59

xmartchat

Dart
3
star
60

pycon-es-workshop

Python
2
star
61

xl-blog

Gatsby XL's Blogpost
JavaScript
2
star
62

node-template

Base template for starting a new Node project
TypeScript
2
star
63

mPOS-SDK-iOS

Objective-C
1
star
64

terraform

HCL
1
star
65

FastlaneDemo

Demo project to show a basic fastlane configuration
Swift
1
star
66

xl-school-automation-web

This is the repository for web automation training for XL
Java
1
star
67

workshop-microservicios

Python
1
star
68

fountain-docs

Fountain documentation
1
star
69

client-side-widget-template

JavaScript templates for a client-side widget
HTML
1
star
70

rn-lightbox

JavaScript
1
star
71

malaria-detector

Jupyter Notebook
1
star
72

SQLiteDSL

1
star
73

terraform-basic-infra

HCL
1
star
74

docker-pcl-cmake

Docker image containing PCL and CMake.
1
star
75

cocoapods-specs

Ruby
1
star
76

simon-ai

This is the repository for the XL Says initiative
Dart
1
star