Convert Figma logo to code with AI

uias logoTabman

™️ A powerful paging view controller with interactive indicator bars

2,836
235
2,836
85

Top Related Projects

22,038

Elegant transition library for iOS & tvOS

12,866

A data-driven UICollectionView framework for building fast and flexible lists.

An elegant and highly customizable presentation API for constructing bottom sheet modals on iOS.

:octocat: 📃 FoldingCell is an expanding content cell with animation made by @Ramotion

5,371

KolodaView is a class designed to simplify the implementation of Tinder like cards on iOS.

:octocat: RAMAnimatedTabBarController is a Swift UI module library for adding animation to iOS tabbar items and icons. iOS library made by @Ramotion

Quick Overview

Tabman is a powerful, customizable tab bar controller for iOS applications. It provides a flexible and feature-rich solution for implementing tab-based navigation in Swift, offering various styles, animations, and customization options to create a seamless user experience.

Pros

  • Highly customizable with numerous built-in styles and animations
  • Easy integration with existing UIViewController-based projects
  • Supports both UIKit and SwiftUI
  • Extensive documentation and active community support

Cons

  • Learning curve for advanced customizations
  • May be overkill for simple tab bar implementations
  • Requires iOS 11.0 or later, which might limit compatibility with older devices
  • Some features may require additional setup or configuration

Code Examples

  1. Basic TabmanViewController setup:
class MyTabViewController: TabmanViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let viewControllers = [
            UIViewController(),
            UIViewController(),
            UIViewController()
        ]
        
        self.dataSource = self
        self.setViewControllers(viewControllers, animated: true)
    }
}

extension MyTabViewController: PageboyViewControllerDataSource {
    func numberOfViewControllers(in pageboyViewController: PageboyViewController) -> Int {
        return viewControllers?.count ?? 0
    }
    
    func viewController(for pageboyViewController: PageboyViewController, at index: PageboyViewController.PageIndex) -> UIViewController? {
        return viewControllers?[index]
    }
    
    func defaultPage(for pageboyViewController: PageboyViewController) -> PageboyViewController.Page? {
        return nil
    }
}
  1. Customizing tab bar appearance:
let bar = TMBar.ButtonBar()
bar.layout.transitionStyle = .snap
bar.indicator.weight = .medium
bar.indicator.tintColor = .systemBlue
bar.buttons.customize { (button) in
    button.tintColor = .gray
    button.selectedTintColor = .black
}
addBar(bar, dataSource: self, at: .top)
  1. Using SwiftUI with Tabman:
struct TabmanView: UIViewControllerRepresentable {
    func makeUIViewController(context: Context) -> TabmanViewController {
        let tabmanViewController = TabmanViewController()
        // Configure Tabman here
        return tabmanViewController
    }
    
    func updateUIViewController(_ uiViewController: TabmanViewController, context: Context) {}
}

Getting Started

  1. Install Tabman using CocoaPods, Carthage, or Swift Package Manager.
  2. Import Tabman in your view controller:
    import Tabman
    import Pageboy
    
  3. Subclass TabmanViewController:
    class MyTabViewController: TabmanViewController {
        // Your implementation here
    }
    
  4. Set up your view controllers and configure the tab bar in viewDidLoad():
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let viewControllers = [/* Your view controllers */]
        self.dataSource = self
        self.setViewControllers(viewControllers, animated: true)
        
        let bar = TMBar.ButtonBar()
        // Customize bar appearance
        addBar(bar, dataSource: self, at: .top)
    }
    
  5. Implement the required PageboyViewControllerDataSource methods.

Competitor Comparisons

22,038

Elegant transition library for iOS & tvOS

Pros of Hero

  • Offers more versatile and complex animations for view transitions
  • Supports interactive gesture-driven transitions
  • Provides a wider range of customization options for animations

Cons of Hero

  • Steeper learning curve due to more complex API
  • May require more setup and configuration for basic transitions
  • Can be overkill for simple tab-based navigation

Code Comparison

Hero:

hero.isEnabled = true
view.hero.id = "heroID"
view.hero.modifiers = [.fade, .scale(0.5)]

Tabman:

let tabBarViewController = TabmanViewController()
tabBarViewController.dataSource = self
tabBarViewController.bar.style = .buttonBar

Key Differences

  • Tabman focuses on tab-based navigation, while Hero is for general view transitions
  • Hero offers more advanced animation capabilities, but Tabman is simpler for basic tab implementations
  • Tabman includes built-in tab bar styles, whereas Hero requires custom UI components

Use Cases

  • Choose Hero for complex, custom transitions between various views
  • Opt for Tabman when implementing straightforward tab-based navigation with minimal setup

Both libraries have their strengths, and the choice depends on the specific requirements of your iOS app's navigation and transition needs.

12,866

A data-driven UICollectionView framework for building fast and flexible lists.

Pros of IGListKit

  • More comprehensive data management solution for complex list-based UIs
  • Optimized for performance with large datasets and frequent updates
  • Robust diffing algorithm for efficient UI updates

Cons of IGListKit

  • Steeper learning curve due to its more complex architecture
  • May be overkill for simpler list-based interfaces
  • Requires more setup and configuration compared to Tabman

Code Comparison

Tabman (Swift):

let tabman = TabmanViewController()
tabman.dataSource = self
tabman.bar.items = [Item(title: "Tab 1"), Item(title: "Tab 2")]

IGListKit (Objective-C):

IGListAdapter *adapter = [[IGListAdapter alloc] initWithUpdater:[[IGListAdapterUpdater alloc] init]
                                                 viewController:self];
adapter.dataSource = self;
[adapter setCollectionView:self.collectionView];

Summary

Tabman is focused on creating tab-based interfaces with a simpler API, while IGListKit provides a more comprehensive solution for complex list-based UIs. IGListKit offers better performance for large datasets but comes with a steeper learning curve. Tabman is easier to implement for basic tab layouts but may not be as suitable for complex, data-driven list interfaces.

An elegant and highly customizable presentation API for constructing bottom sheet modals on iOS.

Pros of PanModal

  • Offers a flexible and customizable bottom sheet presentation style
  • Supports interactive dismissal and drag interactions
  • Provides smooth animations and transitions for modal presentations

Cons of PanModal

  • Limited to bottom sheet-style presentations, less versatile for other tab-based layouts
  • May require more setup and configuration for complex use cases
  • Primarily focused on modal presentations, not suited for persistent navigation

Code Comparison

PanModal:

class ContentViewController: UIViewController, PanModalPresentable {
    var panScrollable: UIScrollView? {
        return tableView
    }
    
    var shortFormHeight: PanModalHeight {
        return .contentHeight(300)
    }
}

Tabman:

class TabViewController: TabmanViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        self.dataSource = self
        self.bar.items = [Item(title: "Tab 1"), Item(title: "Tab 2")]
    }
}

While PanModal focuses on creating customizable bottom sheet presentations with drag interactions, Tabman is designed for creating tab-based interfaces with a variety of bar styles and configurations. PanModal is better suited for modal content presentation, whereas Tabman excels in persistent navigation and content organization.

:octocat: 📃 FoldingCell is an expanding content cell with animation made by @Ramotion

Pros of folding-cell

  • Unique and visually appealing animation for expanding/collapsing cells
  • Highly customizable with various animation options and styles
  • Suitable for creating interactive and engaging list views

Cons of folding-cell

  • Limited to specific use cases (expanding/collapsing cells)
  • May require more setup and customization for complex implementations
  • Potentially higher performance overhead due to animations

Code Comparison

Tabman:

let tabBarController = TabmanViewController()
tabBarController.dataSource = self
tabBarController.bar.style = .buttonBar
tabBarController.addItem(title: "Item 1")
tabBarController.addItem(title: "Item 2")

folding-cell:

let cell = FoldingCell()
cell.itemCount = 2
cell.setup(name: "Cell Title", duration: 0.8, backViewColor: .blue)
cell.selectedAnimation(duration: 0.8, animated: true)
cell.animate(duration: 0.8)

Both libraries offer different functionalities, with Tabman focusing on tab bar management and folding-cell providing an animated cell expansion effect. The choice between them depends on the specific requirements of your project and the desired user interface elements.

5,371

KolodaView is a class designed to simplify the implementation of Tinder like cards on iOS.

Pros of Koloda

  • Specialized for Tinder-like card swiping interfaces
  • Highly customizable card animations and interactions
  • Extensive documentation and example projects

Cons of Koloda

  • Limited to card-based UI, less versatile than Tabman
  • May require more setup for basic functionality
  • Less active maintenance (last updated 2 years ago)

Code Comparison

Koloda (Swift):

let kolodaView = KolodaView()
kolodaView.dataSource = self
kolodaView.delegate = self

func koloda(_ koloda: KolodaView, viewForCardAt index: Int) -> UIView {
    return UIImageView(image: UIImage(named: "card\(index + 1)"))
}

Tabman (Swift):

class TabViewController: TabmanViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        self.dataSource = self
    }
}

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

While both libraries are written in Swift and designed for iOS, they serve different purposes. Koloda focuses on card-swiping interfaces, making it ideal for dating apps or similar card-based UIs. Tabman, on the other hand, is a more versatile tab bar manager that can be used in various app types. The code snippets demonstrate the different setup processes, with Koloda requiring specific card view creation and Tabman focusing on managing multiple view controllers.

:octocat: RAMAnimatedTabBarController is a Swift UI module library for adding animation to iOS tabbar items and icons. iOS library made by @Ramotion

Pros of animated-tab-bar

  • Offers more visually appealing and dynamic animations for tab bar items
  • Provides a wider variety of pre-built animation styles
  • Easier to implement custom animations without extensive knowledge of Core Animation

Cons of animated-tab-bar

  • Less flexible in terms of tab bar positioning and layout customization
  • May have a steeper learning curve for developers new to custom UI components
  • Limited support for advanced features like badge management or tab scrolling

Code Comparison

animated-tab-bar:

let tabBar = RAMAnimatedTabBarController()
let item1 = RAMAnimatedTabBarItem(title: "Home", image: UIImage(named: "home"), tag: 1)
item1.animation = RAMBounceAnimation()
tabBar.viewControllers = [homeVC]
tabBar.setViewControllers([homeVC], animated: false)

Tabman:

class TabViewController: TabmanViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        self.dataSource = self
        self.bar.items = [Item(title: "Home"), Item(title: "Profile")]
    }
}

Summary

animated-tab-bar excels in providing visually appealing animations and pre-built styles, making it ideal for projects prioritizing unique tab bar aesthetics. Tabman, on the other hand, offers more flexibility in tab bar positioning and advanced features, making it suitable for complex tab-based navigation systems. The choice between the two depends on the specific requirements of your project and the desired balance between visual appeal and functionality.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

⭐️ Features

  • Easy to implement page view controller with interactive indicator bars.
  • Highly adaptable and powerful customization.
  • Fully extensible with mix-and-match component library.
  • Built on Pageboy, a simple, informative page view controller.
  • Automatically insets child view controller contents.

📋 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:

  • UINavigationItem
  • UITabBarItem

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
  • backgroundView - TMBarBackgroundView which provides background styling.
  • scrollMode - What type of interactive scrolling to allow.
  • fadesContentEdges - Whether to fade the edges of the bar contents as it goes off-screen.

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
  • contentMode - How the layout should display its contents; either restricted to the bar width with .fit or intrinsically sized with .intrinsic.
  • contentInset - Inset to be applied to the edges of the layout.
  • transitionStyle - How the layout should perform transition animations.
  • alignment - How the layout should be aligned in the bar.

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
  • backgroundView - TMBarBackgroundView which provides background styling.
  • contentInset - Inset to be applied to the edges of the button.
  • transitionStyle (TMBarButtonCollection) - How the buttons should should perform transition animations.
  • badge - TMBadgeView that displays badgeValue from bar item.

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
  • overscrollBehavior - How the indicator should handle scrolling beyond the bounds of the bar items.
  • isProgressive - Whether the indicator should act progressively when transitioning through page indexes.
  • transitionStyle - How the indicator should should perform transition animations.

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

  • TMHorizontalBarLayout - Layout that displays bar buttons sequentially along the horizontal axis.
  • TMConstrainedHorizontalBarLayout - Layout that displays bar buttons sequentially along the horizontal axis, but is constrained by the number of items it can display.

Bar Buttons

  • TMLabelBarButton - Button which contains a single text label.
  • TMTabItemBarButton - Button which mimics appearance of a UITabBarItem, containing a image and label vertically aligned.
  • TMBarButton.None - Display no visible bar buttons.

Bar Indicators

  • TMLineBarIndicator - Simple indicator that displays as a horizontal line.
  • TMChevronBarIndicator - Indicator that displays a vertical chevron centered along the X-axis.
  • TMBlockBarIndicator - Indicator that fills the bar, displaying a solid color.
  • TMDotBarIndicator - Indicator that displays a circular dot centered along the X-axis.
  • TMBarIndicator.None - Display no visible indicator.

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:

  • Tinderbar - Tinder iOS app layout built with Tabman.

📐 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:

  • Updates contentInset and contentOffset appropriately for any UIScrollView or derived subclass found in the child view controller's subviews.
  • Sets additionalSafeAreaInsets to reflect the required safe areas including the bar contents. Any views constrained to the safe area in the child view controller will be laid out correctly (Only available in iOS 11 and above.)

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.