Home

Awesome

<p align="center"> <a href="https://github.com/uias/Tabman"> <img src="https://github.com/uias/Tabman/workflows/Build/badge.svg" /> </a> <img src="https://img.shields.io/badge/Swift-5-orange?logo=Swift&logoColor=white" /> <a href="https://github.com/uias/Tabman/releases"> <img src="https://img.shields.io/github/release/uias/Tabman.svg" /> </a> <a href="https://swift.org/package-manager/"> <img src="https://img.shields.io/badge/SwiftPM-compatible-brightgreen.svg" /> </a> </p>

⭐️ Features

📋 Requirements

Tabman requires iOS 12 or above; and is compatibile with Swift 5.

📲 Installation

Swift Package Manager

Tabman is compatible with Swift Package Manager and can be integrated via Xcode.

CocoaPods

Tabman is also available through CocoaPods:

pod 'Tabman', '~> 3.2'

Carthage

Tabman is also available through Carthage:

github "uias/Tabman" ~> 3.2

🚀 Usage

The Basics

  1. Set up your view controller with the an array of view controllers that you want to appear.
  2. Set the PageboyViewControllerDataSource data source of the TabmanViewController.
  3. Create, customize and add as many TMBars as you want.
import Tabman
import Pageboy

class TabViewController: TabmanViewController {

    private var viewControllers = [UIViewController(), UIViewController()]

    override func viewDidLoad() {
        super.viewDidLoad()

        self.dataSource = self

        // Create bar
        let bar = TMBar.ButtonBar()
        bar.layout.transitionStyle = .snap // Customize

        // Add to view
        addBar(bar, dataSource: self, at: .top)
    }
}

When adding a bar, you can choose to add it to the predefined areas (.top, .bottom, .navigationItem(item:)) or to a custom view with .custom(view:layout:). For more information, read the Adding a Bar guide.

  1. Configure your data sources.
extension TabViewController: PageboyViewControllerDataSource, TMBarDataSource {

    func numberOfViewControllers(in pageboyViewController: PageboyViewController) -> Int {
        return viewControllers.count
    }

    func viewController(for pageboyViewController: PageboyViewController,
                        at index: PageboyViewController.PageIndex) -> UIViewController? {
        return viewControllers[index]
    }

    func defaultPage(for pageboyViewController: PageboyViewController) -> PageboyViewController.Page? {
        return nil
    }

    func barItem(for bar: TMBar, at index: Int) -> TMBarItemable {
        let title = "Page \(index)"
        return TMBarItem(title: title)
    }
}

Bar Items

A bar will ask for a TMBarItemable for each page that is provided to the TabmanViewController dataSource. TMBarItemable is a protocol that can be used for custom item types, the default in Tabman being TMBarItem:

let item = TMBarItem()
item.title = "Item 1"
item.image = UIImage(named: "item.png")
item.badgeValue = "New"

UIKit Itemables

Tabman also provides support for some native UIKit types as TMBarItemable:

These types are unfortunately unable to support the dynamic updating of the bar when setting properties.

Choosing a look

Tabman provides numerous, easy to use template styles out of the box:

These are all available as types of TMBar in TMBar+Templates.

let bar = TMBar.ButtonBar()
let tabBar = TMBar.TabBar()

Customization

Bar customization is available via properties on each functional area of the bar. Each bar is made up of 4 distinct areas:

TMBarView

TMBarView is the root view of every bar, and provides the glue for meshing all the other functional areas together. You can change a few things here, such as background style and transitioning behavior.

bar.background.style = .blur(style: .extraLight)
bar.transitionStyle = .snap

This is also the entry point for all other customization.

🧲 Properties of Interest

More: TMBarView Docs

TMBarLayout

TMBarLayout is the foundation of a TMBarView, dictating how bar buttons are displayed and laid out. Look here if you want to change things such as button spacing, content insets and other layout'y things.

bar.layout.contentInset = UIEdgeInsets(top: 0.0, left: 20.0, bottom: 0.0, right: 20.0)
🧲 Properties of Interest

More: TMBarLayout Docs

TMBarButton

TMBarButton views are populated in the TMBarLayout and correspond to the items provided by the data source. This is the place to change things like fonts, image sizing and highlight colors.

As you will most likely dealing with more than one button, you can modify the whole set at once:

bar.buttons.customize { (button) in
	button.tintColor = .orange
	button.selectedTintColor = .red
}

This will be applied to both existing bar buttons and any that are added to the bar afterwards.

🧲 Properties of Interest

More: TMBarButton Docs

TMBarIndicator

Lastly is TMBarIndicator - which indicates the current page index status for the bar. You can change behavior characteristics here as well as how the indicator looks.

bar.indicator.overscrollBehavior = .compress
bar.indicator.weight = .heavy
🧲 Properties of Interest

More: TMBarIndicator Docs

🎨 Advanced Customization

Tabman provides the complete freedom to mix-and-match the built-in components; and also define your own.

TMBarView leverages generics to define and serve the three distinct functional areas of the bar. This means...

// ...that the preset...
let bar = Bar.ButtonBar()

// ...is actually under the hood:
let bar = BarView<HorizontalBarLayout, LabelBarButton, LineBarIndicator>

So swapping in another type of layout, button or indicator could not be simpler.

Lets say you wanted to actually use a DotBarIndicator rather than the LineBarIndicator:

let bar = BarView<HorizontalBarLayout, LabelBarButton, DotBarIndicator>

The following components are available in Tabman:

Bar Layouts

Bar Buttons

Bar Indicators

Going Completely Custom

As replacing the type of layout, button or indicator is as easy as above; you have the ability to define your own subclasses without too much of a headache.

Custom Tabman Components

There are also example projects that showcase custom layouts and such:

📐 Content Insetting

Tabman automatically adjusts any content in its child view controllers so that it displays correctly beneath any visible bars. It provides the following behaviors:

TabmanViewController also provides barLayoutGuide, a UILayoutGuide that provides top and bottom anchors taking into account any bars added to the .top or .bottom TabmanViewController.BarLocation areas. The raw UIEdgeInsets are also available via .barInsets.

Auto insetting can be disabled by setting automaticallyAdjustsChildInsets to false - however this must be done before viewDidLoad.

Tabman will not provide any insetting behavior for bars that are added to custom views.

⚠️ Troubleshooting

If you are encountering issues with Tabman, please check out the Troubleshooting Guide.

If you're still having problems, feel free to raise an issue.

👨🏻‍💻 About

❤️ Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/uias/Tabman.

👮🏻‍♂️ License

The library is available as open source under the terms of the MIT License.