如何在一个视图中添加多个部分 UICollectionView 单元格

Posted

技术标签:

【中文标题】如何在一个视图中添加多个部分 UICollectionView 单元格【英文标题】:How to add Multiple Section UICollectionViewCells in one view 【发布时间】:2020-05-26 06:06:02 【问题描述】:

我正在尝试在同一个视图中构建多个部分 uicollectionview,第一个集合视图工作正常,但是当我添加第二个集合视图时,应用程序崩溃了(lldb), 两者都是自定义单元格定义了一个我使用的超级类,如本答案所示:[https://***.com/a/44692356/8386142?stw=2][1] 代码很清楚没有错误它只是崩溃了,就像约束有问题(lldb) 这是我用来构建它的代码

import UIKit

struct areaCustomCellData 
    var lable: String


struct storesCustomCellData 
    var lable: String


class Search: UIViewController 

    let data = [
     areaCustomCellData(lable: "شرق النيل"),
     areaCustomCellData(lable: "بحري"),
     areaCustomCellData(lable: "امدرمان"),
     areaCustomCellData(lable: "الخرطوم"),
    ]

    let storesData = [
     storesCustomCellData(lable: "شرق النيل"),
     storesCustomCellData(lable: "بحري"),
     storesCustomCellData(lable: "امدرمان"),
     storesCustomCellData(lable: "الخرطوم"),
    ]

    let areaCView: UICollectionView = 
       let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .horizontal
       let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
        cv.translatesAutoresizingMaskIntoConstraints = false
        cv.register(customCell.self, forCellWithReuseIdentifier: "areaCell")
        cv.backgroundColor = UIColor(red: 245, green: 245, blue: 245, a: 1)
        cv.showsHorizontalScrollIndicator = false
       return cv
    ()

    let storesCView: UICollectionView = 
       let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .vertical
       let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
        cv.translatesAutoresizingMaskIntoConstraints = false
        cv.register(customCell2.self, forCellWithReuseIdentifier: "storesCell")
        cv.backgroundColor = UIColor(red: 245, green: 245, blue: 245, a: 1)
        cv.showsVerticalScrollIndicator = false
       return cv
    ()

    override func viewDidLoad() 
        super.viewDidLoad()

        self.view.backgroundColor = UIColor(red: 245, green: 245, blue: 245, a: 1)
        view.addSubview(areaCView)
        view.addSubview(storesCView)

        storesCView.delegate = self
        storesCView.dataSource = self
        areaCView.delegate = self
        areaCView.dataSource = self

        setUpLayout()
        setUpNavBar()
        setUpSearchBar()

    

    func setUpLayout()
        areaCView.topAnchor.constraint(equalTo: view.topAnchor, constant: 120).isActive = true
        areaCView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
        areaCView.trailingAnchor.constraint(equalTo: view.trailingAnchor,constant: -20).isActive = true
        areaCView.heightAnchor.constraint(equalToConstant: 30).isActive = true

        storesCView.topAnchor.constraint(equalTo: view.topAnchor, constant: 500).isActive = true
        storesCView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
        storesCView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
        storesCView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true

    

extension Search: UICollectionViewDelegateFlowLayout, UICollectionViewDataSource 
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize 
        if indexPath.section == 0 
           return CGSize(width: collectionView.frame.width/4, height: collectionView.frame.height)

        else 
        return CGSize(width: collectionView.frame.width/4, height: collectionView.frame.height)
        
    

    func numberOfSections(in collectionView: UICollectionView) -> Int 
        return 2
    

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 
        return (section == 0) ? data.count : storesData.count
    

    func collectionView(_ collectionView: UICollectionView, cellForItemAt
        indexPath: IndexPath) -> UICollectionViewCell 
        if indexPath.section == 0 
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "areaCell", for: indexPath) as! customCell
            cell.data = self.data[indexPath.row]
            cell.backgroundColor = UIColor.white
            cell.layer.cornerRadius = 10
            return cell

        else
            let cell2 = collectionView.dequeueReusableCell(withReuseIdentifier: "storesCell", for: indexPath) as! customCell2
            cell2.storesData = self.storesData[indexPath.row]
            cell2.backgroundColor = UIColor.white
            cell2.layer.cornerRadius = 10
            return cell2
        


    




class customCell: UICollectionViewCell 

    var data: areaCustomCellData? 
        didSet
            guard let data = data else return

            areaLable.text = data.lable
        
    

    let areaLable: UILabel = 
       let lable = UILabel()
        lable.text = "الخرطوم"
        lable.font = .systemFont(ofSize: 12)
        lable.contentMode = .scaleAspectFit
        lable.clipsToBounds = true
        lable.textAlignment = .center
        lable.translatesAutoresizingMaskIntoConstraints = false
        return lable

    ()

    override init(frame: CGRect) 
        super.init(frame: frame)
        contentView.addSubview(areaLable)

        areaLable.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = true
        areaLable.leadingAnchor.constraint(equalTo: contentView.leadingAnchor).isActive = true
        areaLable.trailingAnchor.constraint(equalTo: contentView.trailingAnchor).isActive = true
        areaLable.bottomAnchor.constraint(equalTo: contentView.bottomAnchor).isActive = true
    

    required init?(coder: NSCoder) 
        fatalError("init(coder:) has not been implemented")
    


class customCell2: UICollectionViewCell 

    var storesData: storesCustomCellData? 
        didSet
            guard let storesData = storesData else return

            storesLable.text = storesData.lable
        
    

    let storesLable: UILabel = 
       let lable = UILabel()
        lable.text = "الخرطوم"
        lable.font = .systemFont(ofSize: 12)
        lable.contentMode = .scaleAspectFit
        lable.clipsToBounds = true
        lable.textAlignment = .center
        lable.translatesAutoresizingMaskIntoConstraints = false
        return lable

    ()

    override init(frame: CGRect) 
        super.init(frame: frame)

        contentView.addSubview(storesLable)
        storesLable.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = true
        storesLable.leadingAnchor.constraint(equalTo: contentView.leadingAnchor).isActive = true
        storesLable.trailingAnchor.constraint(equalTo: contentView.trailingAnchor).isActive = true
        storesLable.bottomAnchor.constraint(equalTo: contentView.bottomAnchor).isActive = true
    

    required init?(coder: NSCoder) 
        fatalError("init(coder:) has not been implemented")
    

崩溃日志

Assertion failure in -[UICollectionView _dequeueReusableViewOfKind:withIdentifier:forIndexPath:viewCategory:], /Library/Caches/com.apple.xbs/Sources/UIKitCore_Sim/UIKit-3920.26.113/UICollectionView.m:5971
2020-05-26 06:49:07.303674+0200 DELEVARE - ديليفري[20979:1173492] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'could not dequeue a view of kind: UICollectionElementKindCell with identifier areaCell - must register a nib or a class for the identifier or connect a prototype cell in a storyboard'
*** First throw call stack:
(
    0   CoreFoundation                      0x0000000106b0cf0e __exceptionPreprocess + 350
    1   libobjc.A.dylib                     0x00007fff208a59b2 objc_exception_throw + 48
    2   CoreFoundation                      0x0000000106b0cc88 +[NSException raise:format:arguments:] + 88
    3   Foundation                          0x0000000104cb5cd2 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 191
    4   UIKitCore                           0x000000011055636e -[UICollectionView _dequeueReusableViewOfKind:withIdentifier:forIndexPath:viewCategory:] + 2426
    5   UIKitCore                           0x000000011055653d -[UICollectionView dequeueReusableCellWithReuseIdentifier:forIndexPath:] + 88
    6   DELEVARE - ديليفري           0x0000000101adb4e5 $s0025DELEVARE____gjoAaHtrbEfbc6SearchC14collectionView_13cellForItemAtSo012UICollectionC4CellCSo0hC0C_10Foundation9IndexPathVtF + 373
    7   DELEVARE - ديليفري           0x0000000101adbbe5 $s0025DELEVARE____gjoAaHtrbEfbc6SearchC14collectionView_13cellForItemAtSo012UICollectionC4CellCSo0hC0C_10Foundation9IndexPathVtFTo + 165
    8   UIKitCore                           0x00000001105409d5 -[UICollectionView _createPreparedCellForItemAtIndexPath:withLayoutAttributes:applyAttributes:isFocused:notify:] + 416
    9   UIKitCore                           0x000000011054082f -[UICollectionView _createPreparedCellForItemAtIndexPath:withLayoutAttributes:applyAttributes:] + 31
    10  UIKitCore                           0x00000001105460cf -[UICollectionView _updateVisibleCellsNow:] + 6402
    11  UIKitCore                           0x000000011054b21e -[UICollectionView layoutSubviews] + 351
    12  UIKitCore                           0x0000000111294848 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 2478
    13  QuartzCore                          0x0000000105e043f0 -[CALayer layoutSublayers] + 255
    14  QuartzCore                          0x0000000105e0a57b _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 523
    15  QuartzCore                          0x0000000105e15c12 _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 80
    16  QuartzCore                          0x0000000105d5ec84 _ZN2CA7Context18commit_transactionEPNS_11TransactionEd + 324
    17  QuartzCore                          0x0000000105d9265f _ZN2CA11Transaction6commitEv + 649
    18  UIKitCore                           0x0000000110daac2b __34-[UIApplication _firstCommitBlock]_block_invoke_2 + 81
    19  CoreFoundation                      0x0000000106a70cdc __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 12
    20  CoreFoundation                      0x0000000106a703d3 __CFRunLoopDoBlocks + 195
    21  CoreFoundation                      0x0000000106a6b1c3 __CFRunLoopRun + 995
    22  CoreFoundation                      0x0000000106a6aac4 CFRunLoopRunSpecific + 404
    23  GraphicsServices                    0x000000010bbacc1a GSEventRunModal + 139
    24  UIKitCore                           0x0000000110d92f80 UIApplicationMain + 1605
    25  DELEVARE - ديليفري           0x0000000101ae046b main + 75
    26  libdyld.dylib                       0x00007fff212f61fd start + 1
    27  ???                                 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb) 

  [1]: https://***.com/a/44692356/8386142?stw=2

【问题讨论】:

可以显示崩溃日志吗? 请添加您的崩溃日志 更新检查日志@King.lbt 【参考方案1】:

崩溃日志显示您没有使用 ViewController 注册您的单元格。 参考这个来解决问题:UICollectionView's cell registerClass in Swift

【讨论】:

【参考方案2】:

无法将类型视图出列:带有标识符 areaCell 的 UICollectionElementKindCell - 必须为标识符注册一个 nib 或一个类,或者连接情节提要中的原型单元

这清楚地告诉你问题是什么,你还没有注册单元格

你可以通过两种方式做到这一点

1) 您可以在属性检查器中设置单元格名称“areaCell” 故事板 2)或者在viewDidLoad中,你可以简单地添加

areaCView.registerClass(customCell.self, forCellWithReuseIdentifier: "areaCell")

【讨论】:

我没有使用故事板 所以就使用第二种方式。 我确实在第一个顶部注册了两个单元格,当在更近的内部声明 collectionView 时,您会发现它 cv.register(customCell.self, forCellWithReuseIdentifier: "areaCell") 只需复制代码并尝试计算出来 将这行代码添加到viewDidLoad并没有解决问题

以上是关于如何在一个视图中添加多个部分 UICollectionView 单元格的主要内容,如果未能解决你的问题,请参考以下文章

多个装饰视图添加到 UICollectionView

如何布局单行集合视图?

如何在视图控制器的多个视图中添加多个渐变颜色

如何在多个视图部分重用 angularjs 数据?

Swift 3:如何在表格视图的多个部分中使用操作按钮?

在drupal 7中,由于多个附件,将表单添加到视图会产生多个相同的表单,如何只保留一个?