• Stars
    star
    722
  • Rank 62,738 (Top 2 %)
  • Language
    Swift
  • License
    MIT License
  • Created over 4 years ago
  • Updated about 1 year ago

Reviews

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

Repository Details

πŸš€ Elegant Pager View fully written in pure SwiftUI.

PagerTabStripView: First pager view built in pure SwiftUI

build and test Platform iOS Swift 5 compatible Carthage compatible CocoaPods compatible License: MIT

Made with ❀️ by Xmartlabs team. XLPagerTabStrip for SwiftUI!

Introduction

PagerTabStripView is the first pager view built in pure SwiftUI. It provides a component to create interactive pager views which contains child views. It allows the user to switch between your views either by swiping or tapping a tab bar item.

Unlike Apple's TabView it provides:

  1. Flexible way to fully customize pager tab views.
  2. Each pagerTabItem view can be of different type.
  3. Bar that contains pager tab item is placed on top.
  4. Indicator view indicates selected child view.
  5. Ability to update pagerTabItem according to highlighted, selected, normal state.
  6. Ability to embed one page within another and not breaking scroll behavior.
  7. Ability to update UI according page selection and transition progress among pages.

Usage

Creating a page view is super straightforward, you just need to place your custom tab views into a PagerTabStripView view and apply the pagerTabItem modifier to each one to specify its navigation bar tab item. The tag parameter is the value to identify the tab item. It can be any Hashable value and it must be unique.

import PagerTabStripView

struct MyPagerView: View {

    var body: some View {

        PagerTabStripView() {
            MyFirstView()
                .pagerTabItem(tag: 1) {
                    TitleNavBarItem(title: "Tab 1")
                }
            MySecondView()
                .pagerTabItem(tag: 2) {
                    TitleNavBarItem(title: "Tab 2")
                }
            if User.isLoggedIn {
                MyProfileView()
                    .pagerTabItem(tag: 3) {
                        TitleNavBarItem(title: "Profile")
                    }
            }
        }

    }
}


To specify the initial selected page you can pass the selection init parameter (for it to work properly this value have to be equal to some tag value of the tab items).

struct MyPagerView: View {

    @State var selection = 1

    var body: some View {
        PagerTabStripView(selection: $selection) {
            MyFirstView()
                .pagerTabItem(tag: 1) {
                    TitleNavBarItem(title: "Tab 1")
                }
            ...
            ..
            .
        }
    }
}

As you may've already noticed, everything is SwiftUI code, so you can update the child views according to SwiftUI state objects as shown above with if User.isLoggedIn.

The user can also configure if the swipe action is enable or not (the swipe is based on a drag gesture) and setup what edges have the gesture disabled.

Params:

  • swipeGestureEnabled: swipe is enabled or not (default is true).
  • edgeSwipeGestureDisabled: is an HorizontalContainerEdge (OptionSet) value where the set could have this options: .left, .right (default is an empty set).

Why is this parameter important? This parameter is important in the context of the next PagerTabStripView example in MyPagerView2. If the pager is on the first page and the user tries to swipe left, it's posible that the parent view container will be triggered instead of the pager's swipe gesture, since the drag gesture can catch the parent view gesture. The edgeSwipeGestureDisabled paramenter prevents this from happening.

struct MyPagerView2: View {

    @State var selection = 1

    var body: some View {
        PagerTabStripView(edgeSwipeGestureDisabled: .constant([.left]),
			  selection: $selection) {
            MyFirstView()
                .pagerTabItem(tag: 1) {
                    TitleNavBarItem(title: "Tab 1")
                }
            ...
            ..
            .
        }
    }
}

Customizing the pager style

PagerTabStripView provides 5 different ways to display the views, which can be selected and customized using the pagerTabStripViewStyle modifier.

Scrollable style

This style allows you to add as many pages as you want. The tabs are placed inside a horizontal scroll for large number of pages.

The customizable settings are:

  • placedInToolbar: If true TabBar items are placed in the NavigationBar. The pager must be a added inside a NavigationView.
  • pagerAnimationOnTap: Animation used when the selection changes.
  • pagerAnimationOnSwipe: Animation used when the drag gesture changes the transaltion.
  • tabItemSpacing: Horizontal margin between TabBar items
  • tabItemHeight: Height of the TabBar items continer.
  • padding: Padding of the TabBar items continer.
  • barBackgroundView: Background view of the TabBar items container.
  • indicatorViewHeight: Height of the indicator view.
  • indicatorView: View representing the indicator view.
struct PagerView: View {

    @State var selection = 1

	var body: some View {
		PagerTabStripView(selection: $selection) {
			MyView()
				.pagerTabItem(tag: 1) {
					TitleNavBarItem(title: "First big width")
				}
			AnotherView()
				.pagerTabItem(tag: 2) {
					TitleNavBarItem(title: "Short")
				}
            ...
            ..
            .

		}
        .pagerTabStripViewStyle(.scrollableBarButton(tabItemSpacing: 15, 
						     tabItemHeight: 50, 
	    					     indicatorView: {
            						Rectangle().fill(.blue).cornerRadius(5)
            					     }))
	}
}

In this example, we add some settings like the tab bar height, indicator view and tab item spaces. Let's see how it looks!

Button bar style

This style places all TabBar items in a container, with each item having the same width. It is ideal for pages with 2-4 pages. The same settings as the Scrollable style can be customized.

The customizable settings are:

  • placedInToolbar: If true TabBar items are placed in the NavigationBar. Pager must be a added inside a NavigationView.
  • pagerAnimationOnTap: Animation used when selection changes.
  • pagerAnimationOnSwipe: Animation used on drag gesture traslation changes.
  • tabItemSpacing: Horizontal margin among tabbar items
  • tabItemHeight: TabBar items continer height
  • padding: TabBar items continer padding
  • barBackgroundView: TabBar items container background view.
  • indicatorViewHeight: Indicator view height
  • indicatorView: View representing the indicator view.
struct PagerView: View {

    @State var selection = "Tab 1"

	var body: some View {
		PagerTabStripView(selection: $selection) {
			MyView()
				.pagerTabItem(tag: "Tab 1") {
					TitleNavBarItem(title: "Tab 1")
				}
			AnotherView()
				.pagerTabItem(tag: "Tab 2") {
					TitleNavBarItem(title: "Tab 2")
				}
			if User.isLoggedIn {
				ProfileView()
					.pagerTabItem(tag: "Profile") {
						TitleNavBarItem(title: "Profile")
                    }
			}
		}
        .pagerTabStripViewStyle(.barButton(tabItemSpacing: 15, 
					   tabItemHeight: 50, 
	    			           indicatorView: {
            				   	Rectangle().fill(.gray).cornerRadius(5)
            				   }))
	}
}

In this example, we add some settings like the tab bar height, indicator view and indicator bar height. Let's see how it looks!

Bar style

This style only displays a bar that indicates the current selected page.

The customizable settings are:

  • placedInToolbar: If set to true, the TabBar items will be placed in the NavigationBar. The Pager must be a added inside a NavigationView.
  • pagerAnimationOnTap: Animation used when the selection changes.
  • pagerAnimationOnSwipe: Animation used when the drag gesture changes the traslation.
  • indicatorViewHeight: Height of the Indicator view.
  • indicatorView: View representing the indicator view.

Segmented style

This style uses a Segmented Picker to indicate the selected page. You can indicate the segmented color, its padding and if you want it to be plced inside the toolbar.

The customizable settings are:

  • placedInToolbar: If true TabBar items are placed in the NavigationBar. The Pager must be a added inside a NavigationView.
  • pagerAnimationOnTap: Animation used when the selection changes.
  • pagerAnimationOnSwipe: Animation used when the drag gesture changes the traslation.
  • backgroundColor: Color of the segmented picker.
  • padding: Padding of the Segmented picker.

Custom style

We can build any custom styles by using bar and scrollablebar styles and providing custom views representing the indicator and the tabbar container view. Check out the example below. There are some other examples in the Example app.

        .pagerTabStripViewStyle(.barButton(placedInToolbar: false,
                                           pagerAnimation: .interactiveSpring(response: 0.5,
                                                                              dampingFraction: 1.00,
                                                                              blendDuration: 0.25),
                                           tabItemHeight: 48,
                                           barBackgroundView: {
            LinearGradient(
               colors: 🌈,
               startPoint: .topLeading,
               endPoint: .bottomTrailing
           )
           .opacity(0.2)
        }, indicatorView: {
            Text("πŸ‘πŸ»").offset(x: 0, y: -24)
        }))

See how it looks:

Navigation bar

The navigation bar supports custom tab bar views for each page. Ypu can specify each tab bar item inline inside the pagerTabItem modifier or in a independent struct by conforming to a View protocol.

For simplicity, we are going to implement a nav bar item with only a title. You can find more examples in the example app.

struct TitleNavBarItem: View {
    let title: String

    var body: some View {
        VStack {
            Text(title)
                .foregroundColor(Color.gray)
                .font(.subheadline)
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        .background(Color.white)
    }
}

Examples

Follow these 3 steps to run Example project

  • Clone PagerTabStripView repo.
  • Open PagerTabStripView workspace.
  • Run the Example project.

Installation

CocoaPods

To install PagerTabStripView using CocoaPods, simply add the following line to your Podfile:

pod 'PagerTabStripView', '~> 4.0'

Carthage

To install PagerTabStripView using Carthage, simply add the following line to your Cartfile:

github "xmartlabs/PagerTabStripView" ~> 4.0

Requirements

  • iOS 16+
  • Xcode 14.2+

Author

Getting involved

  • If you want to contribute 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 and threads on StackOverflow (Tag 'PagerTabStripView') before submitting an issue.

Before contributing, be sure to check the CONTRIBUTING file for more info.

We'd love to hear about your experience with PagerTabStripView. If you use it in your app, drop us a line on Twitter.

More Repositories

1

Eureka

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

XLPagerTabStrip

Android PagerTabStrip for iOS.
Swift
6,880
star
3

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
4

XLActionController

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

Bender

Easily craft fast Neural Networks on iOS! Use TensorFlow models. Metal under the hood.
Swift
1,795
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