HomeTechswift - `setCollectionViewLayout` crash on iOS 14.2 but works well on other...

swift – `setCollectionViewLayout` crash on iOS 14.2 but works well on other systems

[ad_1]

When I hit the button in iOS 14.2 , it will crash and the console will print the follow message:

libc++abi.dylib: terminating with uncaught exception of type NSException
*** Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ‘*** -[__NSDictionaryM setObject:forKey:]: object cannot be nil (key: <NSIndexPath: 0xb53fd3951e2cb315> length = 2, path = 0 – 0)’
terminating with uncaught exception of type NSException

But it works well on other Systems.

here’s the code:

import UIKit

enum DeviceListStyle: String 
    case list
    case flow


class ViewController: UIViewController {
    var style: DeviceListStyle = .list

    private lazy var flowLayout: UICollectionViewFlowLayout = 
        let sizeW = (UIScreen.main.bounds.width - 45) / 2
        let sizeH = sizeW * 120 / 165
        let flowLayout = UICollectionViewFlowLayout()
        flowLayout.itemSize = CGSize(width: sizeW, height: sizeH)
        flowLayout.minimumLineSpacing = 15
        flowLayout.minimumInteritemSpacing = 15
        flowLayout.headerReferenceSize = CGSize(width: UIScreen.main.bounds.width - 30, height: 15)
        flowLayout.footerReferenceSize = CGSize(width: UIScreen.main.bounds.width - 30, height: 15)
        flowLayout.sectionInset.bottom = 15
        return flowLayout
    ()
    
    private lazy var listLayout: UICollectionViewFlowLayout = 
        let sizeW = UIScreen.main.bounds.width - 30
        let sizeH: CGFloat = 70
        let flowLayout = UICollectionViewFlowLayout()
        flowLayout.itemSize = CGSize(width: sizeW, height: sizeH)
        flowLayout.minimumLineSpacing = 10
        flowLayout.minimumInteritemSpacing = 15
        flowLayout.headerReferenceSize = CGSize(width: UIScreen.main.bounds.width - 30, height: 15)
        flowLayout.footerReferenceSize = CGSize(width: UIScreen.main.bounds.width - 30, height: 15)
        flowLayout.sectionInset.bottom = 15
        return flowLayout
    ()
    
    lazy var collectionView: UICollectionView = 
        let layout: UICollectionViewLayout
        switch style 
        case .list:
            layout = listLayout
        case .flow:
            layout = flowLayout
        
        let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
        cv.backgroundColor = .clear
        cv.delegate = self
        cv.dataSource = self
        cv.showsHorizontalScrollIndicator = false
        cv.showsVerticalScrollIndicator = false
        cv.alwaysBounceVertical = true
        cv.alwaysBounceHorizontal = false
        cv.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "cell")
        return cv
    ()
    
    lazy var btn: UIButton = 
        let btn = UIButton()
        btn.center = view.center
        btn.frame.size = CGSize(width: 80, height: 50)
        btn.titleLabel?.textAlignment = .center
        btn.backgroundColor = .black
        btn.setTitle("change", for: .normal)
        btn.addTarget(self, action: #selector(switchStyle), for: .touchUpInside)
        return btn
    ()

    @objc private func switchStyle() 
        switch style 
        case .list:
            self.collectionView.setCollectionViewLayout(self.flowLayout, animated: true)  [weak self] _ in
                guard let self = self else  return 
                self.collectionView.reloadItems(at: self.collectionView.indexPathsForVisibleItems)
            
            self.style = .flow
            
        case .flow:
            self.collectionView.setCollectionViewLayout(self.listLayout, animated: true)  [weak self] _ in
                guard let self = self else  return 
                self.collectionView.reloadItems(at: self.collectionView.indexPathsForVisibleItems)
            
            self.style = .list
        
    
    

    override func viewDidLoad() 
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        collectionView.backgroundColor = .purple
        collectionView.frame = view.bounds
        view.addSubview(collectionView)
        view.addSubview(btn)
    


}


extension ViewController: UICollectionViewDelegate, UICollectionViewDataSource 
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 
        return 1
    
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)
        return cell
    
    
    


[ad_2]

Source link

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments

%d bloggers like this: