xmartlabs / XLPagerTabStrip

Android PagerTabStrip for iOS.
MIT License
6.98k stars 1.33k forks source link

ButtonBar style doesn't fill entire width #256

Closed bdrelling closed 7 years ago

bdrelling commented 8 years ago

I'm really confused by the documentation. I don't see any way without specifically setting a fixed value for self.settings.style.buttonBarItemLeftRightMargin to make the ButtonBar actually take up the full width like the examples in the README.

All four of the animated .gif files at the top have the bar straight across with the tabs justifying to fill the entire width.

Then the animated .gif for ButtonBar looks nothing like them and the one that does (Bar) has no text...

Really confused why there's isn't a way to get a combination of the two?

mtnbarreto commented 7 years ago

I'm not sure if I understood what you are trying to say.

Button Bar view which is the view that contains the tab bars is actually a UICollectionView. Tab Bar items are UICollectionViewCell's. The library calculates the width of each tab bar by adding text width and buttonBarItemLeftRightMargin * 2 so by setting up buttonBarItemLeftRightMargin you are increasing the tab bar size, ultimately it will depends on the title size but at least we can control the left, right marging of each tab.

In addition to that, we can also make the collection view tabs fill its collection view width by setting up buttonBarItemsShouldFillAvailableWidth before call viewDidLoad super implementation.

settings.style.buttonBarItemsShouldFillAvailableWidth = true

I'm gonna update the readme to point this out.

Let me know if this answer your question.

Raymond26 commented 7 years ago

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

Drusy commented 7 years ago

@Raymond26 I am having the same issue, buttonBarItemsShouldFillAvailableWidthdoesn't work until buttonBarItemLeftRightMargin is 0

david-schor commented 7 years ago

@Drusy or @Raymond26 Do you have this code for me? I have tried several things to use he whole width but it didnt work for me. My Code in the Parent is:

import UIKit
import XLPagerTabStrip

class SecurityParentView: ButtonBarPagerTabStripViewController {

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

    override func viewDidLoad() {

        settings.style.buttonBarItemLeftRightMargin = 0
        settings.style.buttonBarItemsShouldFillAvailiableWidth = true

        super.viewDidLoad()

        settings.style.buttonBarBackgroundColor = .white
        settings.style.buttonBarItemBackgroundColor = .white
        settings.style.selectedBarBackgroundColor = purpleInspireColor
        settings.style.buttonBarItemFont = .boldSystemFont(ofSize: 14)
        settings.style.selectedBarHeight = 1.0
        settings.style.buttonBarMinimumLineSpacing = 0
        settings.style.buttonBarItemTitleColor = .black
        settings.style.buttonBarLeftContentInset = 0
        settings.style.buttonBarRightContentInset = 0
        changeCurrentIndexProgressive = { [weak self] (oldCell: ButtonBarViewCell?, newCell: ButtonBarViewCell?, progressPercentage: CGFloat, changeCurrentIndex: Bool, animated: Bool) -> Void in
            guard changeCurrentIndex == true else { return }
            oldCell?.label.textColor = .black
            newCell?.label.textColor = self?.purpleInspireColor
        }
    }

    override func viewControllers(for pagerTabStripController: PagerTabStripViewController) -> [UIViewController] {
        let tabBasics = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "sbBasics")
        let tabLaws = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "sbLaws")
        let tabDefaults = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "sbDefaults")
        return [tabBasics, tabLaws, tabDefaults]
    }

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

    }
}
Drusy commented 7 years ago

@david-schor Here is my setup but I don't think it will help, unfortunately, it depends too much on the number of element and the size of your text in the tabs ...

settings.style.buttonBarBackgroundColor = R.color.light_gray
settings.style.buttonBarItemBackgroundColor = R.color.light_gray
settings.style.selectedBarBackgroundColor = R.color.ps_black
settings.style.buttonBarItemFont = UIFont.exoExtraBoldFont(withSize: 14)
settings.style.selectedBarHeight = 2
settings.style.buttonBarMinimumLineSpacing = 20
settings.style.buttonBarItemTitleColor = R.color.ps_black
settings.style.buttonBarItemsShouldFillAvailableWidth = true

if UIScreen.isIPhone5 {
    settings.style.buttonBarLeftContentInset = 20
    settings.style.buttonBarRightContentInset = 20
} else {
    settings.style.buttonBarLeftContentInset = 40
    settings.style.buttonBarRightContentInset = 40
}
david-schor commented 7 years ago

@Drusy You are right but thank you anyway!

Isuru-Nanayakkara commented 6 years ago

I'm getting this issue as well. Even though I have set buttonBarLeftContentInset to 0.

I have the v8.0.0 installed via CocoaPods.

Here's my setup.

settings.style.buttonBarBackgroundColor = AppColors.blue
settings.style.buttonBarItemBackgroundColor = AppColors.blue
settings.style.selectedBarBackgroundColor = .white
settings.style.buttonBarItemFont = .boldSystemFont(ofSize: 14)
settings.style.selectedBarHeight = 2.0
settings.style.buttonBarMinimumLineSpacing = 0
settings.style.buttonBarItemTitleColor = .white
settings.style.buttonBarItemsShouldFillAvailableWidth = true
settings.style.buttonBarLeftContentInset = 0
settings.style.buttonBarRightContentInset = 0
david-schor commented 6 years ago

Hello @Isuru-Nanayakkara

I asked my problem on stackoverflow and the solution worked: https://stackoverflow.com/questions/46400715/xlpagertabstrip-doesnt-fill-full-width

I hope i could help you

Isuru-Nanayakkara commented 6 years ago

Hi @david-schor, thanks for the reply. But unfortunately that did not work for me either.

Isuru-Nanayakkara commented 6 years ago

I found a solution. Try calling view.setNeedsLayout() and view.layoutIfNeeded() after configuring the settings. Like so,

override func viewDidLoad() {
    settings.style.buttonBarBackgroundColor = AppColors.blue
    settings.style.buttonBarItemBackgroundColor = AppColors.blue
    settings.style.selectedBarBackgroundColor = .white
    settings.style.buttonBarItemFont = .boldSystemFont(ofSize: 14)
    settings.style.selectedBarHeight = 2.0
    settings.style.buttonBarMinimumLineSpacing = 0
    settings.style.buttonBarItemTitleColor = .white
    settings.style.buttonBarItemsShouldFillAvailableWidth = true
    settings.style.buttonBarLeftContentInset = 0
    settings.style.buttonBarRightContentInset = 0

    super.viewDidLoad()

    view.setNeedsLayout()
    view.layoutIfNeeded()
}

This worked for me. I only encountered this issue in iOS 11. That too at random times. It's weird.

Immortalpk commented 5 years ago

I found a solution. Try calling view.setNeedsLayout() and view.layoutIfNeeded() after configuring the settings. Like so,

override func viewDidLoad() {
    settings.style.buttonBarBackgroundColor = AppColors.blue
    settings.style.buttonBarItemBackgroundColor = AppColors.blue
    settings.style.selectedBarBackgroundColor = .white
    settings.style.buttonBarItemFont = .boldSystemFont(ofSize: 14)
    settings.style.selectedBarHeight = 2.0
    settings.style.buttonBarMinimumLineSpacing = 0
    settings.style.buttonBarItemTitleColor = .white
    settings.style.buttonBarItemsShouldFillAvailableWidth = true
    settings.style.buttonBarLeftContentInset = 0
    settings.style.buttonBarRightContentInset = 0

    super.viewDidLoad()

    view.setNeedsLayout()
    view.layoutIfNeeded()
}

This worked for me. I only encountered this issue in iOS 11. That too at random times. It's weird.

@Isuru-Nanayakkara , you are rockstar, you just saved my whole day, Thanks alot.

Please add this in document.

Isuru-Nanayakkara commented 4 years ago

Welp, this issue is back. Apparently my earlier solution of calling view.setNeedsLayout() and view.layoutIfNeeded() doesn't do the trick either.

ezgif com-resize

Demo project

override func viewDidLoad() {
    settings.style.buttonBarBackgroundColor = .clear
    settings.style.buttonBarItemBackgroundColor = .clear
    settings.style.selectedBarBackgroundColor = #colorLiteral(red: 0.07037738711, green: 0.6126742959, blue: 0.9288752675, alpha: 1)
    settings.style.buttonBarItemFont = .systemFont(ofSize: 12)
    settings.style.selectedBarHeight = 3.0
    settings.style.buttonBarMinimumLineSpacing = 0
    settings.style.buttonBarItemTitleColor = UIColor(red: 4/255, green: 30/255, blue: 66/255, alpha: 0.5)
    settings.style.buttonBarItemsShouldFillAvailableWidth = true
    settings.style.buttonBarLeftContentInset = 0
    settings.style.buttonBarRightContentInset = 0

    super.viewDidLoad()

    view.setNeedsLayout()
    view.layoutIfNeeded()
}

I tested on an iPhone running iOS 13.4. I have the latest version 9.0.0 of the project.

StackHelp commented 4 years ago

Here is the solution that works for me and its an easy one

Select your collectionview > Go to Size Inspector > Estimate size > None and Done. :)

Mohamed-Afsar commented 3 years ago
override func viewDidLoad() {
    configureBarStyle()    
    super.viewDidLoad()

    view.setNeedsLayout()
    view.layoutIfNeeded()
}

Though the above-suggested solution fixed the issue by filling the entire width. There were some side effects. 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()