mischa-hildebrand / AlignedCollectionViewFlowLayout

A collection view layout that gives you control over the horizontal and vertical alignment of the cells.
MIT License
1.28k stars 202 forks source link

Crash on Iphone X (iOS 11.2) #7

Open pquy1008 opened 6 years ago

pquy1008 commented 6 years ago

I have implemnted AlignedCollectionViewFlowLayout on my app.

let leftAlignLayout = AlignedCollectionViewFlowLayout(horizontalAlignment: .left, verticalAlignment: .top)
leftAlignLayout.estimatedItemSize = CGSize(width: 1, height: 1)

// Margin
leftAlignLayout.minimumInteritemSpacing = 6
leftAlignLayout.minimumLineSpacing = 6
leftAlignLayout.sectionInset = UIEdgeInsets(top: 6, left: 6, bottom: 6, right: 6)

collectionView.collectionViewLayout = leftAlignLayout

It crash on iPhone X. On iphone 6, 6s and other it works normally. Please help me. screen shot 2018-04-06 at 11 03 22 pm

mischa-hildebrand commented 6 years ago

That's definitely a bug. Obviously, it's not okay to force-unwrap here as the comment says... 😂 Can you post the call stack when it crashes?

One thing that seems awkward to me is that you have an estimated item size of (1, 1). That's like really small. Maybe it's a quick fix to set it to something that's closer to your actual (average) cell size?

yonat commented 6 years ago

Actually small estimatedItemSize is just a way to have the cells auto-sized by AutoLayout.

mischa-hildebrand commented 6 years ago

I know but from my experience the concrete value you set for the estimated item size does have an influence on the layout process, even though, ideally, it shouldn't. I don't know the internals of UICollectionViewFlowLayout but it doesn't hurt to try another (greater) value.

dimovskidamjan commented 6 years ago

I did have a concrete value set for estimatedItemSize and I got the same crash when trying to switch layouts in runtime. Any ideas what might be causing this?

AlexGee17 commented 6 years ago

I've found a temporary fix, this might help to avoid crash on iOS 11 iPhone X

DispatchQueue.main.asyncAfter(deadline: .now() + 0.0){
        self.collectionView.collectionViewLayout = flowLayout
        self.collectionView.contentOffset = .zero
    }
mischa-hildebrand commented 6 years ago

@pquy1008: Can you provide a sample project where the crash occurs? And does it also occur on the simulator for iPhone X? I can't reproduce it. :-|

The stacktrace of the crash might also help.

AlexGee17 commented 6 years ago

@mischa-hildebrand

Yes, this bug also occurs on the simulator, I can provide a sample project later today

mischa-hildebrand commented 6 years ago

@AlexGee17: Any progress with the sample project?

ojoaomorais commented 6 years ago

I fix this issue with the follow code:

if #available(iOS 10.0, *) { alignedFlowLayout.estimatedItemSize = UICollectionViewFlowLayoutAutomaticSize } else { alignedFlowLayout.estimatedItemSize = CGSize(width: 1.0, height: 1.0) }

pmusolino commented 6 years ago

Same problem here (only on iOS 10)

pmusolino commented 6 years ago

Any news? The problem is also present on iOS 11 and iOS 12

shelbygold commented 4 years ago

So I am having the same issue with any iOS versions before iOS 12

                let negativeC: UICollectionView = {

                            let layout = AlignedCollectionViewFlowLayout(horizontalAlignment: .left, verticalAlignment: .center)
                                layout.scrollDirection = .vertical

                                layout.minimumInteritemSpacing = 12
                            layout.sectionInset = UIEdgeInsets(top: 8, left:0, bottom: 0, right: 0)
                            layout.headerReferenceSize = CGSize(width: ImpactConstants.Metrics.screenWidth, height: 40)
                            layout.sectionHeadersPinToVisibleBounds = true
                            layout.estimatedItemSize = CGSize(width: 50, height: 24)

                                let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
                                cv.translatesAutoresizingMaskIntoConstraints = false
                                cv.isUserInteractionEnabled = true
                                cv.backgroundColor = .clear
                                cv.alwaysBounceHorizontal = true
                                cv.clipsToBounds = false
                            cv.allowsMultipleSelection = true
                    cv.register(UICollectionReusableView.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: "negativeHeader")
                                if UIDevice.current.isIpad {
                                    cv.contentInset = UIEdgeInsets(top: 4, left: 0, bottom: 4, right: 100)
                                } else {
                                    cv.contentInset = UIEdgeInsets(top: 4, left: 0, bottom: 4, right: 36)
                                }
                                cv.register(EmotionCollectionCell.self, forCellWithReuseIdentifier: "emotionCollectionCell")
                                return cv
                            }()
        self.negativeCollection = negativeC

Anyway you can help me figure out how to fix it. I have tried to implement all of the changes that you have suggested.

andy-weinstein commented 3 years ago

This library is generally wondeful, but I am getting this bug as well in a kind of obscure case - the collectionView is actually hidden. What I am doing is initializing the selection asychronously after setting up the view, because when the user gets to this, some items need to be preselected. I solved this by calling selectItem with a scroll parameter that causes no scrolling to occur - it's not a documented value, but I found it somewhere in cyberspace, maybe StackOverflow. self.collectionView.selectItem(at: indexPath, animated: false, scrollPosition: .init(rawValue: 0))

Here's a picture of the stacktrace when that last parameter was one of the normal values https://drive.google.com/file/d/1pPkzAd7X91L7pGfL-sHZ-tnE70bnQcSx/view?usp=sharing