xmartlabs / XLPagerTabStrip

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

changeCurrentIndex is not called #180

Open sprint84 opened 8 years ago

sprint84 commented 8 years ago

Using: XLPagerTabStrip 5.0 iOS 9.3

I'm trying to run the following code:

  override func viewDidLoad() {
        settings.style.selectedBarBackgroundColor = UIColor(red: 0.9176470588, green: 0.3058823529, blue: 0.2078431373, alpha: 1.0)
        settings.style.buttonBarBackgroundColor = UIColor(red:0.98, green:0.98, blue:0.98, alpha:1.00)
        settings.style.buttonBarItemBackgroundColor = UIColor(red:0.98, green:0.98, blue:0.98, alpha:1.00)
        settings.style.selectedBarHeight = 3
        settings.style.buttonBarItemFont = UIFont(name: "HelveticaNeue-Medium", size: 12.0)!
        settings.style.buttonBarItemTitleColor = UIColor(red:0.68, green:0.68, blue:0.68, alpha:1.00)

      super.viewDidLoad()

        changeCurrentIndex = { old, new, animated in
            old?.label.textColor = UIColor(white:0.68, alpha:1.0)
            new?.label.textColor = UIColor(white: 0.27, alpha: 1.0)
        }
  }

And the block changeCurrentIndex is never called.

However if I use changeCurrentIndexProgressive it gets called properly.

Thanks

vzsg commented 8 years ago

I think that is the expected behavior, as the ButtonBar is a progressive mode.

sprint84 commented 8 years ago

@vzsg I guess you are right, but the documentation is not clear is this case.

Anyway, there is still a bug in this implementation, regarding the currentIndex.

There are basically two ways to trigger the changeCurrentIndexProgressive block: by swiping left/right or by tapping one of the tab buttons.

I'm trying to read the currentIndex when the page was changed. And when you tap one of the buttons you get the values:

currentIndex = previous index
progress = 1.0

if you swipe horizontally the block is called with the values:

currentIndex = new index
progress = 0.5

That might make sense but it is quite inconsistent. Specially because at initialization the block is called with the values:

currentIndex = new index
progress = 1.0

So it's pretty difficult to know what is the target index based on these values.

The reason seems to be here:

    public func pagerTabStripViewController(pagerTabStripViewController: PagerTabStripViewController, updateIndicatorFromIndex fromIndex: Int, toIndex: Int, withProgressPercentage progressPercentage: CGFloat, indexWasChanged: Bool) {
        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? ButtonBarViewCell
            let newCell = buttonBarView.cellForItemAtIndexPath(NSIndexPath(forItem: currentIndex, inSection: 0)) as? ButtonBarViewCell
            changeCurrentIndexProgressive(oldCell: oldCell, newCell: newCell, progressPercentage: progressPercentage, changeCurrentIndex: indexWasChanged, animated: true)
        }
    }

By the time the block is called here, the currentIndex has not yet been updated, only being updated after the views finish layout.

imadeit commented 8 years ago

Since the delegate can be called, why not added as follows in PagerTabStripViewController.swift?

        if let progressiveDeledate = self as? PagerTabStripIsProgressiveDelegate where pagerBehaviour.isProgressiveIndicator {

            let (fromIndex, toIndex, scrollPercentage) = progressiveIndicatorData(virtualPage)
            progressiveDeledate.pagerTabStripViewController(self, updateIndicatorFromIndex: fromIndex, toIndex: toIndex, withProgressPercentage: scrollPercentage, indexWasChanged: changeCurrentIndex)
            // Leon added
            delegate?.pagerTabStripViewController(self, updateIndicatorFromIndex: fromIndex, toIndex: toIndex)
        }
chenghaoc commented 7 years ago

Any update on this?

chenghaoc commented 7 years ago

I implement following delegate to get the current index:

public protocol PagerTabStripDelegate: class {

    func updateIndicator(for viewController: PagerTabStripViewController, fromIndex: Int, toIndex: Int)
}

public protocol PagerTabStripIsProgressiveDelegate : PagerTabStripDelegate {

    func updateIndicator(for viewController: PagerTabStripViewController, fromIndex: Int, toIndex: Int, withProgressPercentage progressPercentage: CGFloat, indexWasChanged: Bool)
}

just get the toIndex from that

Ashish11111 commented 6 years ago

changeCurrentIndex = { old, new, animated in old?.label.textColor = UIColor(white:0.68, alpha:1.0) new?.label.textColor = UIColor(white: 0.27, alpha: 1.0) }

in this when we click on cell wrong index value got plz help..

maslovsa commented 5 years ago

we are still there

maslovsa commented 5 years ago

my solution

override func updateIndicator(for viewController: PagerTabStripViewController, fromIndex: Int, toIndex: Int, withProgressPercentage progressPercentage: CGFloat, indexWasChanged: Bool) { print(toIndex) }