You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

同一UIViewController中第二个UICollectionView无法加载求助

解决双UICollectionView仅显示一个的问题

看了你的代码和调试发现的问题,核心错误出在numberOfItemsInSection的判断逻辑上——你搞错了判断的对象!

问题根源

你在判断时用的是self.collectionView.tag == 1,但这个self.collectionView是你第一个集合视图的实例,不管当前回调的是哪个CollectionView,你都在检查第一个的标签,自然永远只会进入if分支。如果collectionViewBanner发起回调,你还是返回dataSource.count,要是dataSource为空就直接返回0,导致collectionViewBanner显示空白;就算dataSource有数据,后续cellForItemAt里又会用dataBanner的内容,很可能出现数组越界或显示错乱。

分步修复方案

  1. 修正numberOfItemsInSection的判断逻辑
    要使用方法参数里传入的collectionView来判断,这才是当前正在请求数据的那个集合视图:

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        if collectionView.tag == 1 {
            return self.dataSource.count
        } else if collectionView.tag == 2 {
            return self.dataBanner.count
        }
        return 0
    }
    
  2. 确保两个CollectionView设置了对应Tag
    打开你的Storyboard/XIB:

    • 选中第一个collectionView,在右侧Attributes Inspector里把Tag设为1
    • 选中collectionViewBanner,把Tag设为2
      (Tag值可以自定义,只要和代码里的判断一致就行)
  3. 验证数据源与代理的连接
    防止Storyboard里的连接遗漏,建议在viewDidLoad里手动设置:

    override func viewDidLoad() {
        super.viewDidLoad()
        // 手动绑定数据源和代理
        collectionView.dataSource = self
        collectionViewBanner.dataSource = self
        
        // 原有请求代码
        getBanner { (data) in
            DispatchQueue.main.async {
                self.dataBanner = data
                self.collectionViewBanner.reloadData()
            }
        }
        getAudiobooksAPI { (data) in
            DispatchQueue.main.async {
                self.dataSource = data
                self.collectionView.reloadData()
            }
        }
    }
    
  4. 优化Cell复用的判断逻辑(可选但更严谨)
    你原来用实例对比collectionView == self.collectionView是可行的,但结合Tag判断会更清晰,同时建议给Banner创建独立的Cell子类(避免控件引用错误):

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        if collectionView.tag == 1 {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionViewCell", for: indexPath) as! CollectionViewCell
            let content = self.dataSource[indexPath.item]
            cell.bookLabel.text = content.descricao
            cell.bookImage.setImage(url: content.urlImagem, placeholder: "")
            return cell
        } else if collectionView.tag == 2 {
            // 假设Banner有专门的Cell类CollectionViewBannerCell
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionViewCellBanner", for: indexPath) as! CollectionViewBannerCell
            let content = self.dataBanner[indexPath.item]
            cell.bannerImage.setImage(url: content.urlImagem, placeholder: "")
            return cell
        }
        // 未知的CollectionView,抛出错误便于调试
        fatalError("Received callback from unknown UICollectionView")
    }
    

额外提醒

你在cellForItemAt里给Banner Cell转换的是CollectionViewCell,如果Banner的Cell布局和普通Cell不一样,一定要创建独立的Cell子类,避免出现控件找不到或布局错乱的问题。

内容的提问来源于stack exchange,提问作者Bruno Vavretchek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:59:20