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
相关产品推荐
相关产品推荐

