XLPagerTabStrip: Crash by Index out of range because cachedCellWidths is not synched to viewControllers
Phenomenon
Crash by Index out of range because cachedCellWidths is not synched to viewControllers

fatal error: Index out of range
(lldb) po cachedCellWidths
▿ Optional<Array<CGFloat>>
▿ some : 6 elements
- 0 : 93.0
- 1 : 70.5
- 2 : 94.5
- 3 : 102.5
- 4 : 165.5
- 5 : 151.5
(lldb) po indexPath
▿ 2 elements
- 0 : 0
- 1 : 6
(lldb) po viewControllers.count
8
Analysis
-
self?.reloadPagerTabStripView() // I called reloadPagerTabStripView from my ButtonBarPagerTabStripViewController subclass -
open override func reloadPagerTabStripView() { super.reloadPagerTabStripView() // super.reloadPagerTabStripView() is called before cachedCellWidths is set. So, cachedCellWidths.count is different from viewControllers.count ... cachedCellWidths = calculateWidths() -
// Eventually, following is called first. open func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: IndexPath) -> CGSize { guard let cellWidthValue = cachedCellWidths?[indexPath.row] else { // So, it crashes here.
call stack
#3 0x00000001106ddf4b in ButtonBarPagerTabStripViewController.collectionView(UICollectionView, layout : UICollectionViewLayout, sizeForItemAtIndexPath : IndexPath) -> CGSize
#4 0x00000001106de24c in @objc ButtonBarPagerTabStripViewController.collectionView(UICollectionView, layout : UICollectionViewLayout, sizeForItemAtIndexPath : IndexPath) -> CGSize ()
#5 0x00000001130bfa82 in -[UICollectionViewFlowLayout _getSizingInfosWithExistingSizingDictionary:] ()
#6 0x00000001130c1114 in -[UICollectionViewFlowLayout _fetchItemsInfoForRect:] ()
#7 0x00000001130ba07e in -[UICollectionViewFlowLayout prepareLayout] ()
#8 0x00000001130da215 in -[UICollectionViewData _prepareToLoadData] ()
#9 0x00000001130919c0 in -[UICollectionView _endItemAnimationsWithInvalidationContext:tentativelyForReordering:animator:] ()
#10 0x000000011308e75a in -[UICollectionView _updateRowsAtIndexPaths:updateAction:] ()
#11 0x00000001106dd7b7 in ButtonBarPagerTabStripViewController.cellForItems(at : [IndexPath], reloadIfNotVisible : Bool)
#12 0x00000001106dcfc4 in ButtonBarPagerTabStripViewController.updateIndicator(for : PagerTabStripViewController, fromIndex : Int, toIndex : Int, withProgressPercentage : CGFloat, indexWasChanged : Bool)
#13 0x000000010ea12122 in XXXPagerTabStripController.updateIndicator(for : PagerTabStripViewController, fromIndex : Int, toIndex : Int, withProgressPercentage : CGFloat, indexWasChanged : Bool)
#14 0x00000001106e22a1 in protocol witness for PagerTabStripIsProgressiveDelegate.updateIndicator(for : PagerTabStripViewController, fromIndex : Int, toIndex : Int, withProgressPercentage : CGFloat, indexWasChanged : Bool) -> () in conformance ButtonBarPagerTabStripViewController ()
#15 0x00000001106f40b4 in PagerTabStripViewController.updateContent()
#16 0x00000001106f4c74 in PagerTabStripViewController.reloadPagerTabStripView()
#17 0x00000001106dbdf9 in ButtonBarPagerTabStripViewController.reloadPagerTabStripView()
Environment
- I’m using 7ff9ed755462fe5e4f891868bc7eafd03f8c4355 close to HEAD in master. I believe this problem is not fixed yet. I checked later commit logs.
- It doesn’t happen every time. I don’t know how I can reproduce this problem yet.
About this issue
- Original URL
- State: open
- Created 7 years ago
- Comments: 23 (1 by maintainers)
Commits related to this issue
- Fix index out of range - https://github.com/xmartlabs/XLPagerTabStrip/issues/388#issuecomment-403704224 - https://github.com/wi-hska/HsKAmpus-iOS/issues/68 — committed to wi-hska/XLPagerTabStrip by qultist 6 years ago
- Fix Index out of range crash Reference: https://github.com/xmartlabs/XLPagerTabStrip/issues/388#issuecomment-399786338 — committed to alextov/XLPagerTabStrip by deleted user 5 years ago
- Fix index out of range - https://github.com/xmartlabs/XLPagerTabStrip/issues/388#issuecomment-403704224 - https://github.com/wi-hska/HsKAmpus-iOS/issues/68 — committed to aiaagentapp/XLPagerTabStrip by qultist 6 years ago
- Fix calling reloadPagerTabStripView multiple times ref: https://github.com/xmartlabs/XLPagerTabStrip/issues/388#issuecomment-399786338 — committed to akip-rg/XLPagerTabStrip by akipmaulana 4 years ago
- Fix calling reloadPagerTabStripView multiple times ref: https://github.com/xmartlabs/XLPagerTabStrip/issues/388#issuecomment-399786338 — committed to akip-rg/XLPagerTabStrip by akipmaulana 4 years ago
- Fix corrupted heap crash Fix from https://github.com/xmartlabs/XLPagerTabStrip/issues/388 Only way to fix it is to fork this project, unless the authors update it — committed to emobix/XLPagerTabStrip by deleted user 3 years ago
- Fix crash in buttonbarview issue xmartlabs#575 and issue xmartlabs#388 — committed to Picslo-Corp/XLPagerTabStrip by vjard33 2 years ago
The crash happens when the new
viewControllers.countis greater that the existingviewControllers.count. The problem is thatPagerTabStripViewControllerwhich is the superclass ofButtonBarPagerTabStripViewController, callsupdateContent()before the newcachedCellWidthsare calculated - the calculation is done inButtonBarPagerTabStripViewController.reloadPagerTabStripView()AFTERsuper.reloadPagerTabStripView()is calledHere is a fix for the crash, which postpones the call to
updateContent()after everything is in place:File: ButtonBarPagerTabStripViewController.swift
add a variable:
replace reloadPagerTabStripView() with:
and add this function:
+1
@dasSoumen Have you tried call
self.buttonBarView.layoutIfNeeded()beforeself.reloadPagerTabStripView()?@minhmera try adding self.buttonBarView.layoutIfNeeded() before updateContent() with @nickbit answer. It seems to resolve the issue