david-schor
david-schor

Reputation: 260

XLPagerTabStrip doesn't fill full width

Problem

I'm working on an IOS Application. I use XLPagerTabStrip Library to create Tabs like in Android eg. YouTube. Everything works fine but i have a problem with the Tabs.

I have 3 Tabs but they wont fill out the whole width and they are overlapping themselves.

3 Tabs with the Problem


Paren-Class Code

import UIKit
import XLPagerTabStrip

class InformationsParentView: ButtonBarPagerTabStripViewController {

    let purpleInspireColor = UIColor(red:0.13, green:0.03, blue:0.25, alpha:1.0)

    override func viewDidLoad() {

        super.viewDidLoad()

        settings.style.buttonBarBackgroundColor = .white
        settings.style.buttonBarItemBackgroundColor = .white
        settings.style.selectedBarBackgroundColor = purpleInspireColor
        settings.style.buttonBarItemLeftRightMargin = 0
        settings.style.selectedBarHeight = 2
        settings.style.buttonBarMinimumLineSpacing = 20
        settings.style.buttonBarItemTitleColor = .black
        settings.style.buttonBarItemLeftRightMargin = 0
        settings.style.buttonBarItemsShouldFillAvailiableWidth = true
    }

    override func viewControllers(for pagerTabStripController: PagerTabStripViewController) -> [UIViewController] {
        let tabWorkers = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "sbWorkers")
        let tabPLs = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "sbPLs")
        let tabSuperiors = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "sbSuperiors")

        return [tabWorkers, tabPLs, tabSuperiors]
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

}

StoryBoard

Scene

Scene

Scene

Scene

Attributes Inspector

Attributes Inspector

Size Inspector

Size Inspector


Infos

I have found a solution but it didn't work for me (Github Issue 256):

settings.style.buttonBarItemsShouldFillAvailableWidth = true wouldn't fill the available width for me unless I specified settings.style.buttonBarItemLeftRightMargin = 0 as well.

Has anyone a solution for this?

I'm working with XCode Version 9, Swift 3 and IOS 11.

Upvotes: 3

Views: 3078

Answers (5)

iCanCode
iCanCode

Reputation: 1011

None of the above solutions worked for me except, jcarlos276's answer. https://stackoverflow.com/a/61784184/3549781

Though it fixed the issue there were some side effects like in my case one of the child view controllers had UITableView in it and it was throwing a warning,

[TableView] Warning once only: UITableView was told to layout its visible cells and other contents without being in the view hierarchy (the table view or one of its superviews has not been added to a window). This may cause bugs by forcing views inside the table view to load and perform layout without accurate information (e.g. table view bounds, trait collection, layout margins, safe area insets, etc), and will also cause unnecessary performance overhead due to extra layout passes. Make a symbolic breakpoint at UITableViewAlertForLayoutOutsideViewHierarchy to catch this in the debugger and see what caused this to occur, so you can avoid this action altogether if possible, or defer it until the table view has been added to a window. Table view: <UITableView: 0x7f8366988000; frame = (0 0; 414 822); clipsToBounds = YES; autoresize = RM+BM; gestureRecognizers = <NSArray: 0x600002b2f780>; layer = <CALayer: 0x60000245df20>; contentOffset: {0, 0}; contentSize: {414, 438}; adjustedContentInset: {0, 0, 0, 0}; dataSource: (null)>

This was caused by the following code which asked the view to layout immediately in the func viewDidLoad()

view.setNeedsLayout()
view.layoutIfNeeded()

The actual fix that I came up with was somewhat similar. Instead of asking the whole view to layout itself, I connected an outlet for ButtonBarView and asked it to layout,

buttonBarView.setNeedsLayout()
buttonBarView.layoutIfNeeded()

Upvotes: 1

jguillen
jguillen

Reputation: 189

You need to configure your settings first before calling super.viewDidLoad(), then try by adding view.layoutIfNeeded() after configuring the settings, just as shown below:

override func viewDidLoad() {
    //configure settings first
    configurePagerTabStrip()

    super.viewDidLoad()

    //then
    self.view.layoutIfNeeded()
}

func configurePagerTabStrip() {
    settings.style.buttonBarBackgroundColor = .white
    settings.style.buttonBarItemBackgroundColor = .white
    settings.style.selectedBarBackgroundColor = purpleInspireColor
    settings.style.buttonBarItemLeftRightMargin = 0
    settings.style.selectedBarHeight = 2
    settings.style.buttonBarMinimumLineSpacing = 20
    settings.style.buttonBarItemTitleColor = .black
    settings.style.buttonBarItemLeftRightMargin = 0
    settings.style.buttonBarItemsShouldFillAvailiableWidth = true
}

Upvotes: 2

LogiStack
LogiStack

Reputation: 1006

Open ButtonBarPagerTabStripViewController.swift file in the pod.

In ButtonBarPagerTabStripViewController class definition, remove UICollectionViewDelegate protocol and implement UICollectionViewDelegateFlowLayout protocol.

So change source code

from

open class ButtonBarPagerTabStripViewController: 
    PagerTabStripViewController, PagerTabStripDataSource, 
    PagerTabStripIsProgressiveDelegate, UICollectionViewDelegate, 
    UICollectionViewDataSource {
        ...
}

to

open class ButtonBarPagerTabStripViewController: 
    PagerTabStripViewController, PagerTabStripDataSource, 
    PagerTabStripIsProgressiveDelegate, UICollectionViewDataSource, 
    UICollectionViewDelegateFlowLayout {
        ...
}

I've met that problem when I migrated my app from XCode 8.3.3 to XCode 9. It's pod's problem. If you try it with XCode 8.3.3, you will see no bugs. If you want to use XCode 9, do the above method.

Upvotes: 7

Alexander Khitev
Alexander Khitev

Reputation: 6841

Try this, it's used in the production app and it works for me

   import UIKit
    import XLPagerTabStrip

    class EventsPagerViewController: ButtonBarPagerTabStripViewController {

        /// MARK: - Data

        var routingModel: RoutingModel?

        // MARK: - Lifecycle

        override func viewDidLoad() {
            // change selected bar color
            settings.style.buttonBarBackgroundColor = .white
            settings.style.buttonBarItemBackgroundColor = .white
            settings.style.selectedBarBackgroundColor = ColorManager.mainOrange
            settings.style.buttonBarItemFont = .boldSystemFont(ofSize: 14)
            settings.style.selectedBarHeight = 2.0
            settings.style.buttonBarMinimumLineSpacing = 0
            settings.style.buttonBarItemTitleColor = .black
            settings.style.buttonBarItemsShouldFillAvailableWidth = true
            settings.style.buttonBarLeftContentInset = 0
            settings.style.buttonBarRightContentInset = 0

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

            containerView?.isScrollEnabled = true
            super.viewDidLoad()
            definesPresentationContext = true
            setupNavSettings()        
        }

        override public func viewControllers(for pagerTabStripController: PagerTabStripViewController) -> [UIViewController] {
            let upcomingVC = EventsUpcomingItchesViewController()
            upcomingVC.routingModel = routingModel
            let pastVC = EventsPastItchesViewController()

            // deinit data
            routingModel = nil 
            return [upcomingVC, pastVC]
        }


        private func setupNavSettings() {
            navigationItem.title = "My Events"
        }

    }

Upvotes: 0

Khushbu Desai
Khushbu Desai

Reputation: 1023

Try this one

    buttonBarView.selectedBar.backgroundColor = #colorLiteral(red: 0.1353600621, green: 0.1353642344, blue: 0.1353619695, alpha: 1)


    settings.style.buttonBarBackgroundColor =  .white
    settings.style.buttonBarItemBackgroundColor =  .white

    settings.style.selectedBarHeight = 2.0
    settings.style.selectedBarBackgroundColor = purpleInspireColor


    settings.style.buttonBarItemFont = .boldSystemFont(ofSize: 14)

    settings.style.buttonBarItemTitleColor = .black

    settings.style.buttonBarItemsShouldFillAvailiableWidth = false


    super.viewDidLoad()

buttonBarItemsShouldFillAvailiableWidth = false and make sure that super.viewDidload() is end of the code because i have faced some issues while i am changing indicator info

Upvotes: 1

Related Questions