diff --git a/Example/Example/ButtonBarExampleViewController.swift b/Example/Example/ButtonBarExampleViewController.swift index 5d2157e..3565b2d 100644 --- a/Example/Example/ButtonBarExampleViewController.swift +++ b/Example/Example/ButtonBarExampleViewController.swift @@ -1,4 +1,4 @@ -// ButtonBarExampleViewControlle.swift +// ButtonBarExampleViewController.swift // XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip ) // // Copyright (c) 2016 Xmartlabs ( http://xmartlabs.com ) @@ -25,7 +25,7 @@ import Foundation import XLPagerTabStrip -public class ButtonBarExampleViewControlle: ButtonBarPagerTabStripViewController { +public class ButtonBarExampleViewController: ButtonBarPagerTabStripViewController { var isReload = false @@ -75,4 +75,4 @@ public class ButtonBarExampleViewControlle: ButtonBarPagerTabStripViewController pagerOptions = rand() % 2 == 0 ? pagerOptions.union(.IsElasticIndicatorLimit) : (pagerOptions.remove(.IsElasticIndicatorLimit) ?? pagerOptions) super.reloadPagerTabStripView() } -} \ No newline at end of file +} diff --git a/Example/Example/NavButtonBarExampleViewController.swift b/Example/Example/NavButtonBarExampleViewController.swift index 173bc4e..6323867 100644 --- a/Example/Example/NavButtonBarExampleViewController.swift +++ b/Example/Example/NavButtonBarExampleViewController.swift @@ -29,14 +29,16 @@ public class NavButtonBarExampleViewController: ButtonBarPagerTabStripViewContro var isReload = false public override func viewDidLoad() { + // set up style before super view did load is executed + settings.style.buttonBarBackgroundColor = .clearColor() + settings.style.selectedBarBackgroundColor = .orangeColor() + //- super.viewDidLoad() if pagerOptions.contains(.IsProgressiveIndicator) { pagerOptions = pagerOptions.remove(.IsProgressiveIndicator)! } - buttonBarView.backgroundColor = .clearColor() - buttonBarView.selectedBar.backgroundColor = .orangeColor() buttonBarView.removeFromSuperview() navigationController?.navigationBar.addSubview(buttonBarView) @@ -94,4 +96,9 @@ public class NavButtonBarExampleViewController: ButtonBarPagerTabStripViewContro pagerOptions = rand() % 2 == 0 ? pagerOptions.union(.IsElasticIndicatorLimit) : (pagerOptions.remove(.IsElasticIndicatorLimit) ?? pagerOptions) super.reloadPagerTabStripView() } + + public override func configureCell(cell: ButtonBarViewCell, childInfo: ChildItemInfo) { + super.configureCell(cell, childInfo: childInfo) + cell.backgroundColor = .clearColor() + } } diff --git a/Example/Storyboard.storyboard b/Example/Storyboard.storyboard index 49166e0..cb2f540 100644 --- a/Example/Storyboard.storyboard +++ b/Example/Storyboard.storyboard @@ -288,10 +288,10 @@ - + - + diff --git a/Sources/BaseButtonBarPagerTabStripViewController.swift b/Sources/BaseButtonBarPagerTabStripViewController.swift new file mode 100644 index 0000000..a203423 --- /dev/null +++ b/Sources/BaseButtonBarPagerTabStripViewController.swift @@ -0,0 +1,352 @@ +// TwitterPagerTabStripViewController.swift +// XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip ) +// +// Copyright (c) 2016 Xmartlabs ( http://xmartlabs.com ) +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import Foundation + +public class BaseButtonBarPagerTabStripViewController: PagerTabStripViewController, PagerTabStripViewControllerDataSource, PagerTabStripViewControllerIsProgressiveDelegate, UICollectionViewDelegate, UICollectionViewDataSource { + + public var settings = ButtonBarPagerTabStripSettings() + public var buttonBarItemSpec: ButtonBarItemSpec! + public var changeCurrentIndex: ((oldCell: ButtonBarCellType?, newCell: ButtonBarCellType?, animated: Bool) -> Void)? + public var changeCurrentIndexProgressive: ((oldCell: ButtonBarCellType?, newCell: ButtonBarCellType?, progressPercentage: CGFloat, changeCurrentIndex: Bool, animated: Bool) -> Void)? + + + @IBOutlet public lazy var buttonBarView: ButtonBarView! = { [unowned self] in + var flowLayout = UICollectionViewFlowLayout() + flowLayout.scrollDirection = .Horizontal + flowLayout.sectionInset = UIEdgeInsetsMake(0, self.settings.style.buttonBarLeftContentInset ?? 35, 0, self.settings.style.buttonBarRightContentInset ?? 35) + + let buttonBar = ButtonBarView(frame: CGRectMake(0, 0, self.view.frame.size.width, self.settings.style.buttonBarHeight ?? 44), collectionViewLayout: flowLayout) + buttonBar.backgroundColor = .orangeColor() + buttonBar.selectedBar.backgroundColor = .blackColor() + buttonBar.autoresizingMask = .FlexibleWidth + var newContainerViewFrame = self.containerView.frame + newContainerViewFrame.origin.y = 44 + newContainerViewFrame.size.height = self.containerView.frame.size.height - (44 - self.containerView.frame.origin.y) + self.containerView.frame = newContainerViewFrame + return buttonBar + }() + + lazy private var cachedCellWidths: [CGFloat]? = { [unowned self] in + return self.calculateWidths() + }() + + override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) { + super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) + delegate = self + datasource = self + } + + required public init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + delegate = self + datasource = self + } + + public override func viewDidLoad() { + super.viewDidLoad() + + if buttonBarView.superview == nil { + view.addSubview(buttonBarView) + } + if buttonBarView.delegate == nil { + buttonBarView.delegate = self + } + if buttonBarView.dataSource == nil { + buttonBarView.dataSource = self + } + buttonBarView.scrollsToTop = false + let flowLayout = buttonBarView.collectionViewLayout as! UICollectionViewFlowLayout + flowLayout.scrollDirection = .Horizontal + buttonBarView.showsHorizontalScrollIndicator = false + buttonBarView.backgroundColor = settings.style.buttonBarBackgroundColor ?? buttonBarView.backgroundColor + buttonBarView.selectedBar.backgroundColor = settings.style.selectedBarBackgroundColor ?? buttonBarView.selectedBar.backgroundColor + + // register button bar item cell + switch buttonBarItemSpec! { + case .NibFile(let nibName, let bundle, _): + buttonBarView.registerNib(UINib(nibName: nibName, bundle: bundle), forCellWithReuseIdentifier:"Cell") + case .CellClass: + buttonBarView.registerClass(ButtonBarCellType.self, forCellWithReuseIdentifier:"Cell") + } + //- + } + + public override func viewWillAppear(animated: Bool) { + super.viewWillAppear(animated) + buttonBarView.layoutIfNeeded() + isViewAppearing = true + } + + public override func viewDidAppear(animated: Bool) { + super.viewDidAppear(animated) + isViewAppearing = false + } + + public override func viewDidLayoutSubviews() { + super.viewDidLayoutSubviews() + + guard isViewAppearing || isViewRotating else { return } + + // Force the UICollectionViewFlowLayout to get laid out again with the new size if + // a) The view is appearing. This ensures that + // collectionView:layout:sizeForItemAtIndexPath: is called for a second time + // when the view is shown and when the view *frame(s)* are actually set + // (we need the view frame's to have been set to work out the size's and on the + // first call to collectionView:layout:sizeForItemAtIndexPath: the view frame(s) + // aren't set correctly) + // b) The view is rotating. This ensures that + // collectionView:layout:sizeForItemAtIndexPath: is called again and can use the views + // *new* frame so that the buttonBarView cell's actually get resized correctly + cachedCellWidths = calculateWidths() + buttonBarView.collectionViewLayout.invalidateLayout() + // When the view first appears or is rotated we also need to ensure that the barButtonView's + // selectedBar is resized and its contentOffset/scroll is set correctly (the selected + // tab/cell may end up either skewed or off screen after a rotation otherwise) + buttonBarView.moveToIndex(currentIndex, animated: false, swipeDirection: .None, pagerScroll: .ScrollOnlyIfOutOfScreen) + } + + // MARK: - View Rotation + + public override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) { + super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator) + + isViewRotating = true + coordinator.animateAlongsideTransition(nil) { [weak self] _ in + self?.isViewRotating = false + } + } + + // MARK: - Public Methods + + public override func reloadPagerTabStripView() { + super.reloadPagerTabStripView() + guard isViewLoaded() else { return } + buttonBarView.reloadData() + cachedCellWidths = calculateWidths() + buttonBarView.moveToIndex(currentIndex, animated: false, swipeDirection: .None, pagerScroll: .Yes) + } + + public func calculateStretchedCellWidths(minimumCellWidths: [CGFloat], suggestedStretchedCellWidth: CGFloat, previousNumberOfLargeCells: Int) -> CGFloat { + var numberOfLargeCells = 0 + var totalWidthOfLargeCells: CGFloat = 0 + + for minimumCellWidthValue in minimumCellWidths { + if minimumCellWidthValue > suggestedStretchedCellWidth { + totalWidthOfLargeCells += minimumCellWidthValue + numberOfLargeCells++ + } + } + + guard numberOfLargeCells > previousNumberOfLargeCells else { return suggestedStretchedCellWidth } + + let flowLayout = buttonBarView.collectionViewLayout as! UICollectionViewFlowLayout + let collectionViewAvailiableWidth = buttonBarView.frame.size.width - flowLayout.sectionInset.left - flowLayout.sectionInset.right + let numberOfCells = minimumCellWidths.count + let cellSpacingTotal = CGFloat(numberOfCells - 1) * flowLayout.minimumInteritemSpacing + + let numberOfSmallCells = numberOfCells - numberOfLargeCells + let newSuggestedStretchedCellWidth = (collectionViewAvailiableWidth - totalWidthOfLargeCells - cellSpacingTotal) / CGFloat(numberOfSmallCells) + + return calculateStretchedCellWidths(minimumCellWidths, suggestedStretchedCellWidth: newSuggestedStretchedCellWidth, previousNumberOfLargeCells: numberOfLargeCells) + } + + public func pagerTabStripViewController(pagerTabStripViewController: PagerTabStripViewController, updateIndicatorFromIndex fromIndex: Int, toIndex: Int) throws { + guard shouldUpdateButtonBarView else { return } + buttonBarView.moveToIndex(toIndex, animated: true, swipeDirection: toIndex < fromIndex ? .Right : .Left, pagerScroll: .Yes) + + if let changeCurrentIndex = changeCurrentIndex { + let oldCell = buttonBarView.cellForItemAtIndexPath(NSIndexPath(forItem: currentIndex != fromIndex ? fromIndex : toIndex, inSection: 0)) as? ButtonBarCellType + let newCell = buttonBarView.cellForItemAtIndexPath(NSIndexPath(forItem: currentIndex, inSection: 0)) as? ButtonBarCellType + changeCurrentIndex(oldCell: oldCell, newCell: newCell, animated: true) + } + } + + public func pagerTabStripViewController(pagerTabStripViewController: PagerTabStripViewController, updateIndicatorFromIndex fromIndex: Int, toIndex: Int, withProgressPercentage progressPercentage: CGFloat, indexWasChanged: Bool) throws { + guard shouldUpdateButtonBarView else { return } + buttonBarView.moveFromIndex(fromIndex, toIndex: toIndex, progressPercentage: progressPercentage, pagerScroll: .Yes) + if let changeCurrentIndexProgressive = changeCurrentIndexProgressive { + let oldCell = buttonBarView.cellForItemAtIndexPath(NSIndexPath(forItem: currentIndex != fromIndex ? fromIndex : toIndex, inSection: 0)) as? ButtonBarCellType + let newCell = buttonBarView.cellForItemAtIndexPath(NSIndexPath(forItem: currentIndex, inSection: 0)) as? ButtonBarCellType + changeCurrentIndexProgressive(oldCell: oldCell, newCell: newCell, progressPercentage: progressPercentage, changeCurrentIndex: indexWasChanged, animated: true) + } + } + + // MARK: - UICollectionViewDelegateFlowLayut + + public func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize { + guard let cellWidthValue = cachedCellWidths?[indexPath.row] else { + fatalError("cachedCellWidths for \(indexPath.row) must not be nil") + } + return CGSizeMake(cellWidthValue, collectionView.frame.size.height) + } + + public func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) { + guard indexPath.item != currentIndex else { return } + + buttonBarView.moveToIndex(indexPath.item, animated: true, swipeDirection: .None, pagerScroll: .Yes) + shouldUpdateButtonBarView = false + + let oldCell = buttonBarView.cellForItemAtIndexPath(NSIndexPath(forItem: currentIndex, inSection: 0)) as! ButtonBarCellType + let newCell = buttonBarView.cellForItemAtIndexPath(NSIndexPath(forItem: indexPath.item, inSection: 0)) as! ButtonBarCellType + if pagerOptions.contains(.IsProgressiveIndicator) { + if let changeCurrentIndexProgressive = changeCurrentIndexProgressive { + changeCurrentIndexProgressive(oldCell: oldCell, newCell: newCell, progressPercentage: 1, changeCurrentIndex: true, animated: true) + } + } + else { + if let changeCurrentIndex = changeCurrentIndex { + changeCurrentIndex(oldCell: oldCell, newCell: newCell, animated: true) + } + } + moveToViewControllerAtIndex(indexPath.item) + } + + // MARK: - UICollectionViewDataSource + + public func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { + return viewControllers.count + } + + public func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { + guard let cell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell", forIndexPath: indexPath) as? ButtonBarCellType else { + fatalError("UICollectionViewCell should be or extend from ButtonBarViewCell") + } + let childController = viewControllers[indexPath.item] as! PagerTabStripChildItem + let childInfo = childController.childHeaderForPagerTabStripViewController(self) + + configureCell(cell, childInfo: childInfo) + + if pagerOptions.contains(.IsProgressiveIndicator) { + if let changeCurrentIndexProgressive = changeCurrentIndexProgressive { + changeCurrentIndexProgressive(oldCell: currentIndex == indexPath.item ? nil : cell, newCell: currentIndex == indexPath.item ? cell : nil, progressPercentage: 1, changeCurrentIndex: true, animated: false) + } + } + else { + if let changeCurrentIndex = changeCurrentIndex { + changeCurrentIndex(oldCell: currentIndex == indexPath.item ? nil : cell, newCell: currentIndex == indexPath.item ? cell : nil, animated: false) + } + } + + return cell + } + + // MARK: - UIScrollViewDelegate + + public override func scrollViewDidEndScrollingAnimation(scrollView: UIScrollView) { + super.scrollViewDidEndScrollingAnimation(scrollView) + + guard scrollView == containerView else { return } + shouldUpdateButtonBarView = true + } + + public func configureCell(cell: ButtonBarCellType, childInfo: ChildItemInfo){ + fatalError("You must override this method to set up ButtonBarView cell accordingly") + } + + private func calculateWidths() -> [CGFloat] { + let flowLayout = self.buttonBarView.collectionViewLayout as! UICollectionViewFlowLayout + let numberOfCells = self.viewControllers.count + + var minimumCellWidths = [CGFloat]() + var collectionViewContentWidth: CGFloat = 0 + + for viewController in self.viewControllers { + let childController = viewController as! PagerTabStripChildItem + let childInfo = childController.childHeaderForPagerTabStripViewController(self) + switch buttonBarItemSpec! { + case .CellClass(let widthCallback): + let width = widthCallback(childInfo) + minimumCellWidths.append(width) + collectionViewContentWidth += width + case .NibFile(_, _, let widthCallback): + let width = widthCallback(childInfo) + minimumCellWidths.append(width) + collectionViewContentWidth += width + } + } + + let cellSpacingTotal = CGFloat(numberOfCells - 1) * flowLayout.minimumInteritemSpacing + collectionViewContentWidth += cellSpacingTotal + + let collectionViewAvailableVisibleWidth = self.buttonBarView.frame.size.width - flowLayout.sectionInset.left - flowLayout.sectionInset.right + + if self.buttonBarView.shouldCellsFillAvailiableWidth || collectionViewAvailableVisibleWidth < collectionViewContentWidth { + return minimumCellWidths + } + else { + let stretchedCellWidthIfAllEqual = (collectionViewAvailableVisibleWidth - cellSpacingTotal) / CGFloat(numberOfCells) + let generalMinimumCellWidth = self.calculateStretchedCellWidths(minimumCellWidths, suggestedStretchedCellWidth: stretchedCellWidthIfAllEqual, previousNumberOfLargeCells: 0) + var stretchedCellWidths = [CGFloat]() + + for minimumCellWidthValue in minimumCellWidths { + let cellWidth = (minimumCellWidthValue > generalMinimumCellWidth) ? minimumCellWidthValue : generalMinimumCellWidth + stretchedCellWidths.append(cellWidth) + } + + return stretchedCellWidths + } + } + + private var shouldUpdateButtonBarView = true + private var isViewAppearing = false + private var isViewRotating = false + +} + + +public class ExampleBaseButtonBarPagerTabStripViewController: BaseButtonBarPagerTabStripViewController { + + public override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) { + super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) + initialize() + } + + public required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + initialize() + } + + public func initialize(){ + buttonBarItemSpec = .NibFile(nibName: "ButtonCell", bundle: NSBundle(forClass: ButtonBarViewCell.self), width:{ [weak self] (childItemInfo) -> CGFloat in + let label = UILabel() + label.translatesAutoresizingMaskIntoConstraints = false + label.font = self?.settings.style.buttonBarItemFont + label.text = childItemInfo.title + let labelSize = label.intrinsicContentSize() + return labelSize.width + CGFloat(self?.settings.style.buttonBarItemLeftRightMargin ?? 8 * 2) + }) + } + + public override func configureCell(cell: ButtonBarViewCell, childInfo: ChildItemInfo){ + cell.label.text = childInfo.title + if let image = childInfo.image { + cell.imageView.image = image + } + if let highlightedImage = childInfo.highlightedImage { + cell.imageView.highlightedImage = highlightedImage + } + } +} + diff --git a/Sources/ButtonBarPagerTabStripViewController.swift b/Sources/ButtonBarPagerTabStripViewController.swift index 5065fb9..2056c68 100644 --- a/Sources/ButtonBarPagerTabStripViewController.swift +++ b/Sources/ButtonBarPagerTabStripViewController.swift @@ -24,6 +24,21 @@ import Foundation +public enum ButtonBarItemSpec { + + case NibFile(nibName: String, bundle: NSBundle?, width:((ChildItemInfo)-> CGFloat)) + case CellClass(width:((ChildItemInfo)-> CGFloat)) + + public var weight: ((ChildItemInfo) -> CGFloat) { + switch self { + case .CellClass(let widthCallback): + return widthCallback + case .NibFile(_, _, let widthCallback): + return widthCallback + } + } +} + public struct ButtonBarPagerTabStripSettings { public struct Style { @@ -46,6 +61,15 @@ public class ButtonBarPagerTabStripViewController: PagerTabStripViewController, public var settings = ButtonBarPagerTabStripSettings() + lazy public var buttonBarItemSpec: ButtonBarItemSpec = .NibFile(nibName: "ButtonCell", bundle: NSBundle(forClass: ButtonBarViewCell.self), width:{ [weak self] (childItemInfo) -> CGFloat in + let label = UILabel() + label.translatesAutoresizingMaskIntoConstraints = false + label.font = self?.settings.style.buttonBarItemFont + label.text = childItemInfo.title + let labelSize = label.intrinsicContentSize() + return labelSize.width + (self?.settings.style.buttonBarItemLeftRightMargin ?? 8) * 2 + }) + public var changeCurrentIndex: ((oldCell: ButtonBarViewCell?, newCell: ButtonBarViewCell?, animated: Bool) -> Void)? public var changeCurrentIndexProgressive: ((oldCell: ButtonBarViewCell?, newCell: ButtonBarViewCell?, progressPercentage: CGFloat, changeCurrentIndex: Bool, animated: Bool) -> Void)? @@ -53,13 +77,10 @@ public class ButtonBarPagerTabStripViewController: PagerTabStripViewController, var flowLayout = UICollectionViewFlowLayout() flowLayout.scrollDirection = .Horizontal flowLayout.sectionInset = UIEdgeInsetsMake(0, self.settings.style.buttonBarLeftContentInset ?? 35, 0, self.settings.style.buttonBarRightContentInset ?? 35) - - let buttonBar: ButtonBarView = ButtonBarView(frame: CGRectMake(0, 0, self.view.frame.size.width, self.settings.style.buttonBarHeight ?? 44), collectionViewLayout: flowLayout) + let buttonBar = ButtonBarView(frame: CGRectMake(0, 0, self.view.frame.size.width, self.settings.style.buttonBarHeight ?? 44), collectionViewLayout: flowLayout) buttonBar.backgroundColor = .orangeColor() buttonBar.selectedBar.backgroundColor = .blackColor() buttonBar.autoresizingMask = .FlexibleWidth - var bundle = NSBundle(forClass: ButtonBarView.self) - buttonBar.registerNib(UINib(nibName: "ButtonCell", bundle: bundle), forCellWithReuseIdentifier: "Cell") var newContainerViewFrame = self.containerView.frame newContainerViewFrame.origin.y = 44 newContainerViewFrame.size.height = self.containerView.frame.size.height - (44 - self.containerView.frame.origin.y) @@ -103,6 +124,15 @@ public class ButtonBarPagerTabStripViewController: PagerTabStripViewController, buttonBarView.backgroundColor = settings.style.buttonBarBackgroundColor ?? buttonBarView.backgroundColor buttonBarView.selectedBar.backgroundColor = settings.style.selectedBarBackgroundColor ?? buttonBarView.selectedBar.backgroundColor + // register button bar item cell + switch buttonBarItemSpec { + case .NibFile(let nibName, let bundle, _): + buttonBarView.registerNib(UINib(nibName: nibName, bundle: bundle), forCellWithReuseIdentifier:"Cell") + case .CellClass: + buttonBarView.registerClass(ButtonBarViewCell.self, forCellWithReuseIdentifier:"Cell") + } + //- + } public override func viewWillAppear(animated: Bool) { @@ -292,17 +322,17 @@ public class ButtonBarPagerTabStripViewController: PagerTabStripViewController, for viewController in self.viewControllers { let childController = viewController as! PagerTabStripChildItem - - let label = UILabel() - label.translatesAutoresizingMaskIntoConstraints = false - label.font = settings.style.buttonBarItemFont - label.text = childController.childHeaderForPagerTabStripViewController(self).title - let labelSize = label.intrinsicContentSize() - - let minimumCellWidth = labelSize.width + CGFloat(settings.style.buttonBarItemLeftRightMargin * 2) - minimumCellWidths.append(minimumCellWidth) - - collectionViewContentWidth += minimumCellWidth + let childInfo = childController.childHeaderForPagerTabStripViewController(self) + switch buttonBarItemSpec { + case .CellClass(let widthCallback): + let width = widthCallback(childInfo) + minimumCellWidths.append(width) + collectionViewContentWidth += width + case .NibFile(_, _, let widthCallback): + let width = widthCallback(childInfo) + minimumCellWidths.append(width) + collectionViewContentWidth += width + } } let cellSpacingTotal = CGFloat(numberOfCells - 1) * flowLayout.minimumInteritemSpacing diff --git a/Sources/ButtonCell.xib b/Sources/ButtonCell.xib index 12785a9..4cab761 100644 --- a/Sources/ButtonCell.xib +++ b/Sources/ButtonCell.xib @@ -1,5 +1,5 @@ - + @@ -14,10 +14,11 @@ - + diff --git a/XLPagerTabStrip.xcodeproj/project.pbxproj b/XLPagerTabStrip.xcodeproj/project.pbxproj index f0bd9d5..6624fb9 100644 --- a/XLPagerTabStrip.xcodeproj/project.pbxproj +++ b/XLPagerTabStrip.xcodeproj/project.pbxproj @@ -10,6 +10,7 @@ 281BFDC11C511C420090C26F /* ChildItemInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 281BFDC01C511C420090C26F /* ChildItemInfo.swift */; }; 281BFDC31C511F120090C26F /* PagerTabStripOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 281BFDC21C511F120090C26F /* PagerTabStripOptions.swift */; }; 287D0A6E1C4B73BD004566D6 /* XLPagerTabStripTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 287D0A6D1C4B73BD004566D6 /* XLPagerTabStripTests.swift */; }; + 28C83C841C54229A000B2902 /* BaseButtonBarPagerTabStripViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28C83C831C54229A000B2902 /* BaseButtonBarPagerTabStripViewController.swift */; }; 28E098BE1C5002D90083B788 /* PagerTabStripError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28E098BD1C5002D90083B788 /* PagerTabStripError.swift */; }; 28E098C01C5003130083B788 /* SwipeDirection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28E098BF1C5003130083B788 /* SwipeDirection.swift */; }; 28F828811C494B2C00330CF4 /* XLPagerTabStrip.h in Headers */ = {isa = PBXBuildFile; fileRef = 28F828801C494B2C00330CF4 /* XLPagerTabStrip.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -41,6 +42,7 @@ 281BFDC01C511C420090C26F /* ChildItemInfo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChildItemInfo.swift; sourceTree = ""; }; 281BFDC21C511F120090C26F /* PagerTabStripOptions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PagerTabStripOptions.swift; sourceTree = ""; }; 287D0A6D1C4B73BD004566D6 /* XLPagerTabStripTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = XLPagerTabStripTests.swift; path = Tests/XLPagerTabStripTests.swift; sourceTree = SOURCE_ROOT; }; + 28C83C831C54229A000B2902 /* BaseButtonBarPagerTabStripViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseButtonBarPagerTabStripViewController.swift; sourceTree = ""; }; 28E098BD1C5002D90083B788 /* PagerTabStripError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PagerTabStripError.swift; sourceTree = ""; }; 28E098BF1C5003130083B788 /* SwipeDirection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwipeDirection.swift; sourceTree = ""; }; 28F8287D1C494B2C00330CF4 /* XLPagerTabStrip.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = XLPagerTabStrip.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -101,6 +103,7 @@ CB71C6ED1C4EB988008EC806 /* SegmentedPagerTabStripViewController.swift */, CB0986C31C51391600DF7087 /* ButtonBarPagerTabStripViewController.swift */, CBBD43611C527E80001A748E /* TwitterPagerTabStripViewController.swift */, + 28C83C831C54229A000B2902 /* BaseButtonBarPagerTabStripViewController.swift */, ); name = Controllers; sourceTree = ""; @@ -275,6 +278,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 28C83C841C54229A000B2902 /* BaseButtonBarPagerTabStripViewController.swift in Sources */, CB0986C61C51395E00DF7087 /* ButtonBarView.swift in Sources */, CBBD43621C527E80001A748E /* TwitterPagerTabStripViewController.swift in Sources */, CBA0A1FD1C502DA300C5748C /* BarView.swift in Sources */,