™️ A powerful paging view controller with interactive indicator bars

Overview

⭐️ 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 9 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', '~> 2.11'

Carthage

Tabman is also available through Carthage:

github "uias/Tabman" ~> 2.11

🚀 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.

Comments
  • There is a white space above my child controllers

    There is a white space above my child controllers

    Coming from

    So I have solved the bug stated there, now I am using these codes in my initializeViewControllers :

    let storyboard = UIStoryboard(name: "Landing", bundle: Bundle.main)
            var viewControllers = [UIViewController]()
            var barItems = [Item]()
    
            for index in 0 ..< count {
                var viewControllerChild = UIViewController()
                switch index{
                case 0:
                    viewControllerChild = storyboard.instantiateViewController(withIdentifier: "Me_Favourites_CollectionView_SBID") as! MeFavouritesCollectionViewController
                    barItems.append(Item(title: StringResource.Favourites))
                case 1:
                    viewControllerChild = storyboard.instantiateViewController(withIdentifier: "Wallet_Reload_SBID") as! WalletReloadViewController
                    barItems.append(Item(title: StringResource.Vouchers))
                case 2:
                    viewControllerChild = storyboard.instantiateViewController(withIdentifier: "Me_Events_CollectionView_SBID") as! MeEventsCollectionViewController
                    barItems.append(Item(title: StringResource.Events))
                default :
                    break
                }
                //            viewController.index = index + 1
                viewControllers.append(viewControllerChild)
            }
            
            bar.items = barItems
            self.viewControllers = viewControllers
    

    When I land on my parent vc, there is a white space between the child and the custom UIView from the parent vc. And scrolling left and right will remove the white space. I have recorded 2 videos and sent you through email, please have a look.

    bug 
    opened by junweimah 22
  • Custom Tabbar with Image and Title

    Custom Tabbar with Image and Title

    It is not bug but it is kind of feature. Is it possible in Tabman to get a view like attached image. I want scrollable Tabbar with Image and Title and selected item size different and not selected different plus all the data in Tabbar will be coming from API not static data. Please guide me if it possible in this.

    screenshot_20170624-170524

    opened by krishnameena 22
  • How do I go directly to second or third tab when coming to the parent vc?

    How do I go directly to second or third tab when coming to the parent vc?

    So I have some checking before bringing user to the parent's vc which holds all the tabs.

    So lets say in parent tab, I have 3 tabs.

    After user is done doing something in a previous screen, I want to bring user to the second tab, how do I open the parent's vc and directly lands user in the second tab?

    Thanks

    bug needs reproduction steps 
    opened by junweimah 18
  • Table Rows behind TabBar

    Table Rows behind TabBar

    All of the UIViewControllers added to the bar are TableViewControllers. It appears that the first row of the table ends up behind the bar. I thought the automatic inset would take care of this. Am I missing something? Please advise.

    bug 
    opened by ghost 18
  • Adding Carthage Support

    Adding Carthage Support

    • Adding Cartfile with Payboy and PureLayout
    • Updating Tabman workspace to link those 2 libraries
    • Updating Travis file to with carthage script
    • Updating Readme
    • Removing Podfile for Example project and just relying on compiled libraries
    opened by soheilbm 17
  • How to embedBar in navigationItem.titleView ?

    How to embedBar in navigationItem.titleView ?

    New Issue Checklist

    Issue Description

    This is my code, I used embedBar to do it, but it wasn't work!

    import UIKit
    import Tabman
    import Pageboy
    
    class ViewController: TabmanViewController, PageboyViewControllerDataSource {
        func numberOfViewControllers(in pageboyViewController: PageboyViewController) -> Int {
            return 4
        }
        
        func viewController(for pageboyViewController: PageboyViewController, at index: PageboyViewController.PageIndex) -> UIViewController? {
            return UIViewController()
        }
        
        func defaultPage(for pageboyViewController: PageboyViewController) -> PageboyViewController.Page? {
            return nil
        }
        
    
        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view, typically from a nib.
            self.dataSource = self
            
            // configure the bar
            self.bar.items = [Item(title: "Page 1"),
                              Item(title: "Page 2")]
            
            let tabbarView = UIView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width-80, height: 44))
            tabbarView.backgroundColor = UIColor.blue
            self.embedBar(in: tabbarView)
            
            self.navigationItem.titleView = tabbarView
        }
    
    
    }
    

    Other useful things

    improvement 
    opened by Jinkeycode 16
  • Feature Request - Show / Hide Bar explicitly

    Feature Request - Show / Hide Bar explicitly

    New Issue Checklist

    Issue Description

    Hi, we're looking for a way to show / hide the Tabman bar explicitly, i.e. programmatically.

    Our usecase is to show the bar after any user interaction (touches) and after a short time interval we'd like to hide the bar. Furthermore this show / hide process should be animated, ideally using a constraint that will increase / decrease the bar views hight.

    We're using tabman to show the titles of several pages we're displaying using pageboy. But we don't want the bar / titles to be visible all the time, as this is not important or wanted by the user (the screen should be as clean as possible while reading).

    Other useful things

    We already have the logic to detect touches and a timer to trigger the tabman's potential show / hide methods. So what we effectively need is just a way to either call a show / hide method on the tabman controller or alternatively a constraint we can manipulate to our needs.

    I just forked your project, but saw that there's already a tabman 2 in the making, so I wanted to hear your opinion first, maybe you're already working on such a feature? If not you're going to?

    improvement 
    opened by ChristianSteffens 14
  • Automatically handle child controller insetting

    Automatically handle child controller insetting

    In addition to the requiredContentInset property in TabmanBarConfig, Tabman should automatically handle insetting child view controllers within the page view controller.

    This should also be able to be disabled via an opt-out property in TabmanViewController.

    new feature 
    opened by msaps 13
  • RTL Issue in Indicator

    RTL Issue in Indicator

    Thanks for amazing Library. I have an issue related to RTL. When I change language from English to Arabic then the indicator remains at the non selected part as shown in video. You can see "Pending" option is selected but indicator shown behind the "Cancelled" button. When I drag the controller a little then the indicator working fine. Can you please help me with that. Here is the code I write Screenshot 2019-07-21 at 8 46 01 PM

    ezgif com-video-to-gif

    Thanks

    needs verification 
    opened by Salmancs43 12
  • Can we add badge number on TabItems

    Can we add badge number on TabItems

    opened by aman198 12
  • Crash when I scroll a little bit fast to the right/left

    Crash when I scroll a little bit fast to the right/left

    Hi, if I scroll to the right/left between the tabs a little bit fast and many times, I got the following error. It happened especially on the simulator and randomly on phone.

    *** Assertion failure in -[UIPageViewController _flushViewController:animated:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3694.4.18/UIPageViewController.m:2124
    *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Don't know about flushed view <UIView: 0x7fb92953cc60; frame = (0 0; 375 603); autoresize = W+H; layer = <CALayer: 0x60c00022b2e0>>'
    *** First throw call stack:
    (
    	0   CoreFoundation                      0x000000010a9f81cb __exceptionPreprocess + 171
    	1   libobjc.A.dylib                     0x000000010a35af41 objc_exception_throw + 48
    	2   CoreFoundation                      0x000000010a9fd362 +[NSException raise:format:arguments:] + 98
    	3   Foundation                          0x0000000109dff089 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 193
    	4   UIKit                               0x000000010be7e707 -[UIPageViewController _flushViewController:animated:] + 584
    	5   UIKit                               0x000000010be7e7c0 -[UIPageViewController queuingScrollView:didFlushView:animated:] + 156
    	6   UIKit                               0x000000010bf9a5be -[_UIQueuingScrollView _flushView:animated:] + 117
    	7   UIKit                               0x000000010bf9a796 -[_UIQueuingScrollView _replaceViews:updatingContents:adjustContentInsets:animated:] + 446
    	8   UIKit                               0x000000010bf9d383 -[_UIQueuingScrollView setView:direction:animated:completion:] + 552
    	9   UIKit                               0x000000010be7a503 -[UIPageViewController _setViewControllers:withScrollInDirection:animated:completion:] + 685
    	10  UIKit                               0x000000010be7a70a -[UIPageViewController setViewControllers:direction:animated:completion:] + 268
    	11  Pageboy                             0x0000000108a9702b _T07Pageboy0A14ViewControllerC12scrollToPageSbAC0F0O_Sb8animatedySo06UIViewC0C_S2btcSg10completiontFTf4nngn_n + 1659
    	12  Pageboy                             0x0000000108a9636d _T07Pageboy0A14ViewControllerC12scrollToPageSbAC0F0O_Sb8animatedySo06UIViewC0C_S2btcSg10completiontF + 29
    	13  Tabman                              0x000000010935eecb _T06Tabman0A14ViewControllerC3baryAA0A3BarC_Si15didSelectItemAttFTo + 107
    	14  Tabman                              0x000000010935efb1 _T06Tabman0A14ViewControllerCAA0A12BarResponderA2aDP3baryAA0aD0C_Si15didSelectItemAttFTW + 33
    	15  Tabman                              0x000000010934f097 _T06Tabman0A9ButtonBarC03tabB7PressedySo8UIButtonCFTf4gn_n + 407
    	16  Tabman                              0x000000010934b42a _T06Tabman0A9ButtonBarC8textFontSo6UIFontCfsToTm + 42
    	17  UIKit                               0x000000010b4f69bd -[UIApplication sendAction:to:from:forEvent:] + 83
    	18  UIKit                               0x000000010b66d183 -[UIControl sendAction:to:forEvent:] + 67
    	19  UIKit                               0x000000010b66d4a0 -[UIControl _sendActionsForEvents:withEvent:] + 450
    	20  UIKit                               0x000000010b66c3cd -[UIControl touchesEnded:withEvent:] + 618
    	21  UIKit                               0x000000010bad3a88 _UIGestureEnvironmentSortAndSendDelayedTouches + 5560
    	22  UIKit                               0x000000010bacd93e _UIGestureEnvironmentUpdate + 1483
    	23  UIKit                               0x000000010bacd327 -[UIGestureEnvironment _deliverEvent:toGestureRecognizers:usingBlock:] + 484
    	24  UIKit                               0x000000010bacc3d3 -[UIGestureEnvironment _updateGesturesForEvent:window:] + 288
    	25  UIKit                               0x000000010b56c45c -[UIWindow sendEvent:] + 4102
    	26  UIKit                               0x000000010b511802 -[UIApplication sendEvent:] + 352
    	27  UIKit                               0x000000010be43a50 __dispatchPreprocessedEventFromEventQueue + 2809
    	28  UIKit                               0x000000010be465b7 __handleEventQueueInternal + 5957
    	29  CoreFoundation                      0x000000010a99b2b1 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
    	30  CoreFoundation                      0x000000010aa3ad31 __CFRunLoopDoSource0 + 81
    	31  CoreFoundation                      0x000000010a97fc19 __CFRunLoopDoSources0 + 185
    	32  CoreFoundation                      0x000000010a97f1ff __CFRunLoopRun + 1279
    	33  CoreFoundation                      0x000000010a97ea89 CFRunLoopRunSpecific + 409
    	34  GraphicsServices                    0x0000000112c219c6 GSEventRunModal + 62
    	35  UIKit                               0x000000010b4f4d30 UIApplicationMain + 159
    	36  Stylehaus                           0x00000001081fd747 main + 55
    	37  libdyld.dylib                       0x000000010b3d7d81 start + 1
    	38  ???                                 0x0000000000000001 0x0 + 1
    )
    libc++abi.dylib: terminating with uncaught exception of type NSException
    
    bug needs verification high 
    opened by JeromeCHA 12
  • RTL Bar not go to the right

    RTL Bar not go to the right

    New Issue Checklist

    Issue Description

    Hi, I am trying to add 2 tabs only, but the tabs start from the lest not from the right, how i can flip it to start from the right of the screen as per the Arabic language is RTL

    Other useful things

    https://user-images.githubusercontent.com/2632226/208249225-bb12f702-ad2f-40cd-af14-97325f6ef98c.mp4

    opened by mfa01 0
  • Setting badge for given tab when tab is not currently selected

    Setting badge for given tab when tab is not currently selected

    New Issue Checklist

    Issue Description

    I am attempting to set the badge value of a tab, while that tab is not the one currently visible. For example, I want tab 3 to update its badge value, while tab 5 is the currently selected one. I know my functions and notification methods are working fine, because I am able to console log a test string to ensure that it is being hit. It appears that the only time a badge can be updated, is when the tab the badge belongs to, is the currently selected tab.

    Other useful things

    N/A

    opened by bstillitano 1
  • Loading large numbers of tab (around 50)

    Loading large numbers of tab (around 50)

    I have searched in existing issues but could not find any solution.

    I have situations where i need to create multiple webview which i'm handling through tabman. problem is it is taking too much time to load and app kind of stuck for some seconds.

    Implementation is really straightforward and according to docs.

    class TabViewController: TabmanViewController {
             override func viewDidLoad() {
            super.viewDidLoad()
            
            self.dataSource = self
            
            let bar = TMBarView<TMConstrainedHorizontalBarLayout, TMTabItemBarButton, TMLineBarIndicator>()
            bar.buttons.customize {
                
                $0.tintColor = Asset.lightBlue.color
                $0.selectedTintColor = Asset.darkSkyBlue.color
                $0.font = FontFamily.MyriadPro.bold.font(size: 14)
                $0.adjustsFontForContentSizeCategory = true
                
            }
            
            bar.spacing = 16
            bar.fadesContentEdges = false
            bar.layout.transitionStyle = .snap // Customize 
            let systembar = bar.systemBar()
            systembar.backgroundStyle = .flat(color: UIColor.white)
            
            self.addBar(systembar,
                        dataSource: self,
                        at: .top)
            self.loadSelectedWebsites()
        }
    
        func loadData() {
           for selectedWebsite in self.selectedWebsites {
                let webController = StoryboardScene.Main.webViewController.instantiate()
                webController.delegate = self
                webController.websiteURL = selectedWebsite.url
                self.viewControllers.append(webController)
            }
            self.reloadData()
        }
    }
    

    and class conforms to datasource delegates of Tabman

    opened by maasim94 0
  • how to disable one specified button ?

    how to disable one specified button ?

    I have 4 tab buttons, and want to disable all except the first. How to do it? I know how to disable swipe, but wonder is it possible to dim tab both visually and interactive. Thanks

    opened by djdance 0
  • [HELP Needed] Async tab image

    [HELP Needed] Async tab image

    first thank you for great library. I have situation where tab image would come from server (async call) is there way in library to load image from URL instead of local image?

    opened by maasim94 0
Releases(3.0.1)
  • 3.0.1(Nov 8, 2022)

  • 3.0.0(Nov 2, 2022)

  • 2.13.0(Aug 20, 2022)

  • 2.12.0(Jan 15, 2022)

  • 2.11.1(Mar 30, 2021)

  • 2.11.0(Mar 8, 2021)

    Added

    • Support for Dynamic Type to TMLabelBarButton with adjustsFontForContentSizeCategory.
    • Support for Dynamic Type to TMTabItemBarButton with adjustsFontForContentSizeCategory.
    Source code(tar.gz)
    Source code(zip)
  • 2.10.0(Jan 23, 2021)

  • 2.9.1(Jul 20, 2020)

  • 2.9.0(May 4, 2020)

    Updated

    • Dropped support for legacy Swift (4.x) versions.
    • Pageboy to 3.6.

    Update Notes

    This release drops support for Swift 4.x, meaning Tabman will now require Swift 5 going forwards. To use Tabman with a Swift 4 codebase, you must use Tabman 2.8.2 or older.

    Source code(tar.gz)
    Source code(zip)
  • 2.8.2(Apr 25, 2020)

  • 2.8.1(Apr 21, 2020)

  • 2.8.0(Jan 12, 2020)

    Improvements to TMLabelBarButton 🏷

    Added

    • verticalAlignment to TMLabelBarButton to allow for button contents to be vertically aligned.

    Fixed

    • Issue where TMLabelBarButton would fail to resize correctly when using custom fonts.
    Source code(tar.gz)
    Source code(zip)
  • 2.7.0(Jan 2, 2020)

    Improvements to layouts and insetting 🍺

    Added

    • centerDistributed to TMBarLayout.Alignment to center align all bar buttons.

    Updated

    • Removed AutoInsetter as a dependency.
    • Child insetting logic now utilises additionalSafeAreaInsets only on iOS 11 and above.

    Fixed

    • #449 Infinite loop that could be caused by recursive layout calls.
    • #487 Issue where child contents could be requested to layout before being added to the view hierarchy.
    • #478 Issue where bar could fail to inset children when created dynamically for the page view controller.
    Source code(tar.gz)
    Source code(zip)
  • 2.6.3(Oct 6, 2019)

  • 2.6.2(Oct 3, 2019)

  • 2.6.1(Sep 11, 2019)

  • 2.6.0(Sep 11, 2019)

    Improved iOS 13 support and more 📲

    Added

    • Support for Swift Package Manager in Xcode 11.
    • Support for Dark Mode in iOS 13.
    • contentInset to TMBadgeView allowing for custom badge content insets.

    Fixed

    • Issue where accessing safeAreaLayoutGuide could cause a crash on Jailbroken devices.
    • Issue where constraints in TMTabItemBarButton would not correctly be applied on iOS 13.
    • Issue where a TMSystemBar could fail to correctly extend background edges into system areas.
    Source code(tar.gz)
    Source code(zip)
  • 2.5.0(Aug 3, 2019)

    Support for vertical separators 🚀

    Added

    • Support for vertical separators between bar buttons to TMHorizontalBarLayout via showSeparators.
    • separatorColor to TMHorizontalBarLayout.
    • separatorInset to TMHorizontalBarLayout.
    • separatorWidth to TMHorizontalBarLayout.
    Source code(tar.gz)
    Source code(zip)
  • 2.4.3(Jul 13, 2019)

  • 2.4.2(Apr 25, 2019)

  • 2.4.1(Apr 20, 2019)

  • 2.4.0(Apr 19, 2019)

    Added

    • #398 Ability to override automatic inset values via calculateRequiredInsets() on TabmanViewController.
    • #404 adjustsAlphaOnSelection to TMBarButton.
    • #338 Ability to hide / show the bar with TMHidingBar.
    • #403 Accessibility support to TMBarView.
    • #403 Accessibility support to TMBarItem.
    • #403 Accessibility support to TMBarButton.
    • #321 navigationItem(item:) to TabmanViewController.BarLocation with support for embedding a TMBar in a UINavigationBar.

    Updated

    • Make TMBarItem open.
    • Make .title open on TMBarItem.
    • Make .image open on TMBarItem.
    • Make .badgeValue open on TMBarItem.
    • Make .items open on TMBarView.
    • Make .dataSource open on TMBarView.
    • Make .delegate open on TMBarView.
    • Make .scrollMode open on TMBarView.
    • Make .fadesContentEdges open on TMBarView.
    • Make .spacing open on TMBarView.
    • #396 Improved layout adaptability of TMTabItemBarButton on iPad and in landscape.
    • #404 TMBarButton no longer performs default fade transition in update(for selectionState:)
    Source code(tar.gz)
    Source code(zip)
  • 2.3.0(Mar 31, 2019)

  • 2.2.1(Mar 24, 2019)

  • 2.2.0(Mar 8, 2019)

    Support for Bar Button Badges 🔴

    Added

    • #363 .alignment property to TMBarLayout to adjust content alignment.
    • #378 .spacing property to TMBarView to adjust spacing between bar content / accessory views.
    • #373 setNeedsUpdate() to TMBarItemable to allow for dynamic item updates.
    • #387 Ability to show badges on TMBarButton via .badgeValue on TMBarItemable.
    • #392 tabmanParent to UIViewController.
    • #392 tabmanBarItems to UIViewController.

    Updated

    • #378 Improved bar transitioning behavior when adjusting selected tab.
    • #373 .title is now mutable on TMBarItemable.
    • #373 .image is now mutable on TMBarItemable.

    Upgrade Notes

    There is unfortunately a breaking change in TMBarItemable for any conforming types by making .title, .image settable and introducing .badgeValue.

    Source code(tar.gz)
    Source code(zip)
  • 2.1.4(Feb 23, 2019)

  • 2.1.3(Jan 14, 2019)

    Fixed

    • #366 Incorrect indicator positioning when using a Right-to-Left language.

    Updated

    • #368 Improve access controls in TMBarIndicator and subclasses.
    • #368 Improve access controls in TMBarButton.
    • #368 Improve access controls in TMBarLayout.
    Source code(tar.gz)
    Source code(zip)
  • 2.1.2(Dec 29, 2018)

  • 2.1.1(Dec 24, 2018)

    Updated

    • Make TMHorizontalBarLayout properties open.
    • Make TMConstrainedHorizontalBarLayout properties open.
    • Make TMLabelBarButton open.
    • Make TMTabItemBarButton open.

    Fixed

    • #358 Fix typo of TMBarDataSource in README.
    Source code(tar.gz)
    Source code(zip)
  • 2.1.0(Dec 19, 2018)

Owner
UI At Six
Pure UIKit gravy
UI At Six
A scroll pager that displays a list of tabs (segments) and manages paging between given views

ScrollPager A scroll pager similar to the one in Flipboard. The control creates a tabbar given a title or an image, and has the option of connecting t

Aryan Ghassemi 512 Aug 31, 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 fun, easy-to-use tab bar navigation controller for iOS.

CircleBar Don’t you, sometimes, miss fun user interfaces? Truth is, we do. Sure, you can't use them in enterprise apps for obvious reasons, but if you

softhaus 786 Dec 25, 2022
A custom tab bar controller for iOS.

ESTabBarController ESTabBarController is a custom tab bar controller for iOS. It has a tab indicator that moves animated along the bar when switching

null 122 Oct 6, 2022
Folding Tab Bar and Tab Bar Controller

FoldingTabBar.iOS Folding Tab Bar and Tab Bar Controller Inspired by this project on Dribbble Also, read how it was done in our blog Requirements iOS

Yalantis 3.7k Dec 21, 2022
A custom tab bar controller for iOS written in Swift 4.2

A custom tab bar controller for iOS written in Swift 4.0 Screenshots Installation Cocoa Pods: pod 'AZTabBar' Swift Package Manager: You can use The Sw

Antonio Zaitoun 335 Dec 11, 2022
A lightweight customized tabbar view. 📌

A lightweight customized tabbar view. Screenshots Features Installation Setup ToDos Credits Thanks License Screenshots Features Easily Configurable an

Hemang 137 Dec 16, 2022
Pager is the simplest and best way to implement sliding view controllers in Swift

Pager is the simplest and best way to implement sliding view controllers. Installation Drop in the Spring folder to your Xcode project. Or via CocoaPo

Lucas Oceano 234 Aug 5, 2022
A simple and easily customizable InputAccessoryView for making powerful input bars with autocomplete and attachments

InputBarAccessoryView Features Autocomplete text with @mention, #hashtag or any other prefix A self-sizing UITextView with an optional fixed height (c

Nathan Tannar 968 Jan 2, 2023
A simple and easily customizable InputAccessoryView for making powerful input bars with autocomplete and attachments

InputBarAccessoryView Features Autocomplete text with @mention, #hashtag or any other prefix A self-sizing UITextView with an optional fixed height (c

Nathan Tannar 968 Jan 2, 2023
A paging menu controller built from other view controllers placed inside a scroll view (like Spotify, Windows Phone, Instagram)

Unfortunately, life gets in the way sometimes and I won't be able to maintain this library any longer and upgrade this library to where it needs to be

null 5.2k Dec 31, 2022
Paging view controller and scroll tab view

TabPageViewController Description TabPageViewController is paging view controller and scroll tab view. Screenshot Infinity Mode Limited Mode Customiza

M 1.3k Jan 7, 2023
Floating indicator, mimicrate to indicator which appear when silent mode turn on / off. Support large texts.

SPIndicator About Mimicrate to indicator which appear when silent mode turn on / off. Availalbe 2 animated presets: done & error. Also support custom

Ivan Vorobei 568 Dec 30, 2022
Recording Indicator Utility lets you turn off the orange microphone recording indicator light for live events and screencasts.

Recording Indicator Utility Recording Indicator Utility lets you turn off the orange microphone recording indicator light, making it ideal for profess

Tyshawn Cormier 121 Jan 1, 2023
A paging view controller with a highly customizable menu ✨

Getting Started | Customization | Installation Features Parchment lets you page between view controllers while showing any type of generic indicator t

Martin Rechsteiner 3k Jan 8, 2023
A framework for presenting bars and view controllers as popup, much like the look and feel of Apple Music App.

PBPopupController PBPopupController is a framework for presenting bars and view controllers as popup, much like the look and feel of Apple Music App.

Patrick 58 Dec 3, 2022
Interactive notification pop-over (aka "Toast) modeled after the iOS AirPods and Apple Pencil indicator.

Interactive notification pop-over (aka "Toast) modeled after the iOS AirPods and Apple Pencil indicator. Installation The recommended way is to use Co

Philip Kluz 108 Nov 11, 2022
Infinite paging controller, scrolling through contents and title bar scrolls with a delay

PageController PageController is infinite paging controller, scrolling through contents and title bar scrolls with a delay. Then it provide user inter

Hirohisa Kawasaki 408 Nov 28, 2022
Infinite paging controller, scrolling through contents and title bar scrolls with a delay

PageController PageController is infinite paging controller, scrolling through contents and title bar scrolls with a delay. Then it provide user inter

Hirohisa Kawasaki 408 Nov 28, 2022
🌊 - Jelly is a library for animated, non-interactive & interactive viewcontroller transitions and presentations with the focus on a simple and yet flexible API.

Jelly is a library for animated, non-interactive & interactive viewcontroller transitions and presentations with the focus on a simple and yet flexibl

Sebastian Boldt 2.4k Dec 25, 2022