当 UICollectionView 嵌套在 UITableVIew 中时,无法进行选择

Selection is not possible when UICollectionView is nested in UITableVIew

提问人:John Cromartie 提问时间:12/7/2012 最后编辑:Alex CioJohn Cromartie 更新时间:3/14/2023 访问量:4061

问:

我有一个每个单元格都包含一个.UITableViewUICollectionView

我可以垂直滚动并水平滚动嵌套,但是我不能在 .UITableViewUICollectionViewUICollectionViewCellUICollectionView

在 中禁用选择,在 中启用(默认状态)。UITableViewUICcollectionView

根本就没有被调用过。UICollectionView'scollectionView:didSelectItemAtIndexPath:

iOS Objective-C UITableView iOS6 UIColictionView

评论

0赞 Sean Kladek 5/10/2013
是否设置了 UICollectionViewDelegate?
0赞 gabriel_vincent 5/15/2013
集合视图中的单元格是否呈现任何点击响应(如调暗或类似内容)?也许的单元格正在取消集合视图的点击。UITableView
3赞 Dave Haigh 9/11/2013
你找到这个约翰的解决方法了吗?
0赞 Alex Cio 3/26/2015
你有没有找到让它发挥作用的解决方案?结合水平和垂直滚动总是一个问题,因为每个都有自己的行为,而且它们在一起不再那么灵敏了,我对解决方案很感兴趣!UIScrollView

答:

-1赞 calql8edkos 5/17/2013 #1

我的第一直觉是,两种视图之间的手势识别器可能是冲突的

更具体地说,点击的 UITableView GR 可能会阻止 UICollectionView GR 接收触摸

0赞 Jonathan Ellis 1/13/2015 #2

我能够解决这个问题的方法是向单元格添加一个点击手势识别器以手动处理点击,而不是依赖未被调用的:didSelectRowAtIndexPath

迅速

let tapRecognizer = UITapGestureRecognizer(target: self, action: "cellTapped:")
tapRecognizer.numberOfTapsRequired = 1
cell.addGestureRecognizer(tapRecognizer)

Objective-C语言

UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(cellTapped:)];
tapRecognizer.numberOfTapsRequired = 1;
[cell addGestureRecognizer:tapRecognizer];

现在,您可以在该方法中处理正在点击的单元格,并且可以通过 获取对点击的单元格的引用。cellTapped:tapRecognizer.view

-1赞 Abhi 4/3/2015 #3

首先,请检查您是否提供了必要的数据源和委托。 然后,如果您在特定数量的表格视图单元格上使用集合视图,则可以直接放在原型单元格中。请确保您的单元格有适当的限制(宽度)

-3赞 André Slotta 4/22/2015 #4

这应该根本不是问题!无需自定义手势识别器。无需禁用 TableView 的选择。

请务必:

  1. 在情节提要或代码中设置 TableView,并设置其数据源和委托
  2. 在 CellForrowAtIndexPath 中,将 TableViewCell 取消排队后,获取对相应 CollectionView 的引用,并设置其 (CollectionView) 数据源和委托
  3. 实现 TableView 和 CollectionViews 委托 didSelect 方法,并记录其调用以查看其工作

在我写这个答案之前,我刚刚实现了一个小的例子项目,以确保没有问题。如果它仍然不适合您,我可以上传它!

祝你好运!

0赞 xlnunez 7/19/2016 #5

我刚刚完成了这项工作,所以我想我会与你们分享我的解决方案。

在为 和 嵌套设置必要的委托和数据源后,您可以创建第一个可选择的视图,如下所示UITableViewUICollectionViewUICollectionView

- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath  {
    ...
    [tableViewCell bringSubviewToFront:tableViewCell.yourCollectionView];
    return cell;
}

这将使第一个可通过委托选择的内容UICollectionView

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath; 

视图的任何其他部分都将使用委托进行选择UITableView

- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;

希望这有帮助!

-1赞 dive 11/17/2016 #6

尝试禁用 for 并确保正确设置集合视图。delaysContentTouchestableViewdelegate

-1赞 Pablo Alegre 11/9/2018 #7

我已经用故事板和程序化进行了测试,并且它按预期工作。我收到 collectionView:didSelectItemAtIndexPath: 或 tableView:didSelectRowAtIndexPath,具体取决于点击的区域。似乎,至少在较新的 SDK(我的是 11.4)中,它是固定的。

0赞 eja08 6/28/2021 #8

自定义中的所有视图都应相对于 进行布局。因此,请始终将它们添加为子视图,并且选择应该有效。UITableViewCellcontentViewcontentView

class CustomTableViewCell: UITableViewCell {
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)

        let view = UIView()
        contentView.addSubview(view)

        // layout
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}
0赞 Abhishek Biswas 3/14/2023 #9

在 viewController 中

import UIKit

class ViewController: UIViewController {
    
    @IBOutlet weak var tableView: UITableView!{
        didSet{
            tableView.delegate = self
            tableView.dataSource = self
            tableView.register(UINib(nibName: "TableViewCell", bundle: nil), forCellReuseIdentifier: TableViewCell.cellId)
        }
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }
}

extension ViewController : UITableViewDelegate, UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 5
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell =  tableView.dequeueReusableCell(withIdentifier: TableViewCell.cellId, for: indexPath) as! TableViewCell
        return cell
    }
}

在 TableViewCell 文件中

import UIKit

class TableViewCell: UITableViewCell {
    
    static let cellId = "TableViewCell"
    
    @IBOutlet weak var collectionView: UICollectionView!  {
        didSet{
            collectionView.delegate = self
            collectionView.dataSource = self
            collectionView.register(UINib(nibName: "CollectionViewCell", bundle: nil), forCellWithReuseIdentifier: CollectionViewCell.cellId)
        }
    }
    

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
        
        // Configure the view for the selected state
    }
}


extension TableViewCell : UICollectionViewDelegate, UICollectionViewDataSource {
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 5
    }
    
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: CollectionViewCell.cellId, for: indexPath) as! CollectionViewCell
        cell.labelThing.text = "samples text"
        return cell
    }
    
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        print("Hello world")
    }
}

在 CollectionView 文件中

import UIKit

class CollectionViewCell: UICollectionViewCell {
    
    static let cellId = "CollectionViewCell"

    @IBOutlet weak var labelThing: UILabel!
    
    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

}