ios UITableView中嵌套UICollectionView时无法进行选择

hgncfbus  于 2023-03-20  发布在  iOS
关注(0)|答案(9)|浏览(291)

我有一个UITableView,其中每个单元格包含一个UICollectionView
我可以垂直滚动UITableView,也可以水平滚动嵌套的UICollectionView,但是我 * 不能 * 在UICollectionView中选择UICollectionViewCell
UITableView中禁用选择,而在UICcollectionView中启用(默认状态)。
UICollectionView'scollectionView:didSelectItemAtIndexPath:根本就不会被调用。

r7knjye2

r7knjye21#

我能够解决这个问题的方法是在单元格中添加一个点击手势识别器来手动处理点击,而不是依赖于didSelectRowAtIndexPath,因为didSelectRowAtIndexPath不会被调用:

雨燕

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

目标-C

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

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

q3qa4bjr

q3qa4bjr2#

我刚刚开始工作所以我想我应该和你们分享我的解决方案。
在为UITableView和嵌套的UICollectionView设置了必要的委托和数据源之后,您可以将UICollectionView作为第一个可选视图,如下所示

- (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;

希望这有帮助!

fkaflof6

fkaflof63#

你在一个定制的UITableViewCell中拥有的所有视图都应该相对于contentView进行布局,所以总是把它们作为一个子视图添加到contentView中,选择应该起作用。

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")
    }
}
68bkxrlz

68bkxrlz4#

在视图中控制器

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
    }
}

在TableView单元格文件中

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")
    }
}

在集合视图文件中

import UIKit

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

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

}
4szc88ey

4szc88ey5#

我的第一直觉是这两个视图之间的姿势识别器可能是冲突的
更具体地,敲击的UITableViewGR可能阻止UICollectionViewGR接收触摸

kzmpq1sx

kzmpq1sx6#

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

pbwdgjma

pbwdgjma7#

尝试禁用tableViewdelaysContentTouches,并确保集合视图的delegate设置正确。

m2xkgtsf

m2xkgtsf8#

我已经用故事板和编程进行了测试,它正如预期的那样工作。我收到collectionView:didSelectItemAtIndexPath:或者tableView:didSelectRowAtIndexPath取决于点击的区域。看起来,至少在较新的SDK(我的是11. 4)中,它是固定的。

ndasle7k

ndasle7k9#

这不应该是一个问题在所有!no自定义手势识别器需要. no需要到禁用这tableview的选择.
请务必:
1.在情节提要或代码中设置tableview并设置其数据源和委托
1.在cellforrowatindexpath中,在使tableviewcell出队之后,获取对相应集合视图的引用,并设置其(集合视图)数据源和委托
1.实现tableviews和collectionviews委托didselect方法,并记录它们的调用以查看其工作情况
我只是实现了一个小的例子项目之前,我写的答案,以确保没有问题。我可以上传它,如果它仍然不为您工作!
祝你好运!

相关问题