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

UICollectionView嵌套UICollectionViewCell无法横向滚动求助

嵌套UICollectionView横向滚动失效问题

我尝试在UICollectionViewCell内实现横向滚动的UICollectionView,目前元素和背景都能正常显示,但内层横向CollectionView无法滚动;外层竖向CollectionView滚动正常。

外层CollectionView及Cell相关代码

(场景Prop4和Countries会加载内层横向CollectionView)

lazy var collView: UICollectionView = {
    let sub = SubclassedCollectionViewCell.self
      
    let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
    layout.itemSize = CGSize(width: self.view.frame.width, height:self.view.frame.height/100)
    layout.scrollDirection = .vertical
    layout.sectionInset = UIEdgeInsets(top:100, left: 0, bottom: 100, right: 0)
    print("the frame",self.view.frame)
    let view = UICollectionView(frame: CGRect(x:0, y:0, width: self.view.frame.width, height: self.view.frame.height), collectionViewLayout: layout)
    view.register(sub, forCellWithReuseIdentifier: "profInfo")
    view.backgroundColor = .clear
    view.isUserInteractionEnabled = true
    view.dataSource = self
    view.delegate = self

    return view
}()

public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let myCell = collectionView.dequeueReusableCell(withReuseIdentifier: "profInfo", for: indexPath) as! SubclassedCollectionViewCell
    myCell.isUserInteractionEnabled = true
    myCell.frame = CGRect(x: 10, y: (indexPath.row+1)*75, width: Int(self.view.frame.width) - 10, height: 50)
    myCell.backgroundColor = .clear
    let v = UIView(frame: CGRect(x: 0, y: 0, width: 150, height: 50))
    let v2 = UIView(frame: CGRect(x: 150, y: 0, width: Int(self.view.frame.width) - 160, height: 50))
    let label = UILabel(frame: CGRect(x: 0, y: 0, width: 200, height: 21))
    let label2 = UILabel(frame: CGRect(x: 0, y: 0, width: 200, height: 21))
    let imageV = UIImageView(frame: CGRect(x: 0, y: 12.5, width: 25, height: 25))
    let imageV2 = UIImageView(frame: CGRect(x: 0, y: 12.5, width: 25, height: 25))

    label.center = CGPoint(x: 150, y: 25)
    label.textColor = .white
    label2.textColor = .white
    label2.center = CGPoint(x: 115, y: 25)
    label2.textAlignment = .center
    imageV2.center = CGPoint(x: 115, y: 25)
    label.text = prof!.arrInfo[indexPath.row].title + ":"
    print("array info", prof!.arrInfo)

    switch(prof!.arrInfo[indexPath.row].title){
    case "Prop1" :
        imageV.image = UIImage(named: "art.scnassets/prop1.png")?.resized(to: CGSize(width: 10, height: 10))
        label2.text = prof!.arrInfo[indexPath.row].text
        v2.addSubview(label2)
        break;
    case "DOB" :
        imageV.image = UIImage(named: "art.scnassets/DOB.png")?.resized(to: CGSize(width: 10, height: 10))
        label2.text = getDOBFormat(dateStr: prof!.arrInfo[indexPath.row].text!)
        v2.addSubview(label2)
        break;
    case "Prop3" :
        imageV.image = UIImage(named: "art.scnassets/prop3.png")?.resized(to: CGSize(width: 10, height: 10))
        imageV2.image = UIImage(named: prof!.arrInfo[indexPath.row].text!)?.resized(to: CGSize(width: 10, height: 10))
        break;
    case "Prop4" :
        imageV.image = UIImage(named: "art.scnassets/prop4.png")?.resized(to: CGSize(width: 10, height: 10))
        collectionViews[prof!.arrInfo[indexPath.row].title] = GeneralCollectionView()
        collectionViews[prof!.arrInfo[indexPath.row].title]?.type = "Images"
        collectionViews[prof!.arrInfo[indexPath.row].title]?.data = prof!.arrInfo[indexPath.row].selected
        myCell.contentView.addSubview(collectionViews[prof!.arrInfo[indexPath.row].title]!.Container)
        break;
    case "Countries" :
        imageV.image = UIImage(named: "art.scnassets/translation.png")?.resized(to: CGSize(width: 10, height: 10))
        collectionViews[prof!.arrInfo[indexPath.row].title] = GeneralCollectionView()
        collectionViews[prof!.arrInfo[indexPath.row].title]?.type = "Countries"
        collectionViews[prof!.arrInfo[indexPath.row].title]?.data = prof!.arrInfo[indexPath.row].selected
        myCell.contentView.addSubview(collectionViews[prof!.arrInfo[indexPath.row].title]!.Container)
        break;
    case "location":
        imageV.image = UIImage(named: "art.scnassets/location.png")?.resized(to: CGSize(width: 10, height: 10))
        label2.text = prof!.arrInfo[indexPath.row].text
        v2.addSubview(label2)
        break;
    default:
        break;
    }
    v.addSubview(label)
    v.addSubview(imageV)
    v2.addSubview(imageV2)
    myCell.contentView.addSubview(v)
    myCell.contentView.addSubview(v2)

    return myCell
}

内层横向CollectionView代码

public class GeneralCollectionView:NSObject,UICollectionViewDelegate,UICollectionViewDataSource{
    
    weak var parent:AnyObject?
    var data:[String]?
    var type:String?
    
    lazy var Container: UICollectionView = {
        let sub = SubclassedCollectionViewCell.self
        
        let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
        layout.itemSize = CGSize(width: 50, height:50)
        layout.scrollDirection = .horizontal
        let view = UICollectionView(frame: CGRect(x:150, y:0, width: 250, height: 50), collectionViewLayout: layout)
        view.showsHorizontalScrollIndicator = false
        view.isDirectionalLockEnabled = true
        view.isScrollEnabled = true
        view.isPagingEnabled = true
        view.isUserInteractionEnabled = true
        view.alwaysBounceHorizontal = true
        view.clipsToBounds = true
        view.translatesAutoresizingMaskIntoConstraints = false
        view.register(sub, forCellWithReuseIdentifier: "myGenCell")
        view.dataSource = self
        view.delegate = self
        view.backgroundColor = .white
        layout.sectionInset = UIEdgeInsets(top:0, left: 10, bottom: 0, right: 10)
        layout.minimumLineSpacing = 10  // space between rows
        layout.minimumInteritemSpacing = 5  // space between items in the same
        layout.itemSize = CGSize(width: 50, height: 50)

        return view
    }()
    
    public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return data!.count
    }
    
    public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let myCell = collectionView.dequeueReusableCell(withReuseIdentifier: "myGenCell", for: indexPath) as! SubclassedCollectionViewCell
        myCell.isUserInteractionEnabled = true
        if type == "Countries"{
            let country = data![indexPath.item].split(separator: "-")
            let label = UILabel()
            label.frame.size = CGSize(width: 50, height: 50)
            label.text = countryFlag(country: String(country[1]))
            label.center = CGPoint(x: 30, y: 25)
            myCell.contentView.addSubview(label)
            print(label, countryFlag(country: String(country[1])))
        } else {
            let val = data![indexPath.item]
            let imgView = UIImageView()
            imgView.frame.size = CGSize(width: 20, height: 20)
            imgView.image = UIImage(named: val)?.resized(to: CGSize(width: 25, height: 25))
            imgView.center = CGPoint(x: 30, y: 25)
            myCell.contentView.addSubview(imgView)
        }
        return myCell
    }
}

解决要点

  • 布局约束冲突:内层CollectionView设置了translatesAutoresizingMaskIntoConstraints = false但未添加任何约束,导致实际布局位置或尺寸异常,无法响应触摸。要么删除这个属性,保持frame布局有效;要么添加明确的NSLayoutConstraints来固定其在Cell内的位置和大小。
  • Cell手动frame问题:外层Cell的frame是手动设置的,这会和CollectionViewFlowLayout的itemSize冲突,导致Cell布局混乱,影响内层视图的交互区域。建议通过FlowLayout的itemSize来控制Cell大小,不要手动修改Cell的frame。
  • 视图层级遮挡:代码中给Cell的contentView添加了v、v2等视图,检查这些视图的frame是否覆盖了内层CollectionView,导致触摸事件被拦截。可以调整视图层级,确保内层CollectionView在最上层,或者缩小v、v2的宽度避免覆盖。
  • Cell复用问题:每次cellForItemAt都会新建GeneralCollectionView,不仅浪费内存,还可能导致复用Cell时交互异常。应该将GeneralCollectionView的实例放在SubclassedCollectionViewCell内部,复用Cell时直接更新数据即可。
  • 交互属性确认:确保内层CollectionView的isUserInteractionEnabled、isScrollEnabled始终为true,没有被后续代码意外修改。

内容的提问来源于stack exchange,提问作者Camille Basbous

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 22:10:09