当水平滚动 collectionview 时,如何确定选择了哪个 tableView Cell

How can I figure out which tableView Cell is selected when collectionview is scrolled horizontally

我在 TableViewCell 中有 collectionView。 TableView 有 1 个部分和 4 行。

我想知道水平滚动collectionView时选中了tableviewcell的哪一行

我试图通过将 tableView 行放入 "var nowRow" 变量中来找出答案,如下面的代码所示。但它不起作用。

如何找出选中了tableviewcell的哪一行?

class Home2ViewController: UIViewController, UITableViewDataSource,  UITableViewDelegate, UICollectionViewDataSource, UICollectionViewDelegate {

    var posts = [Post]()
    var nowRow = Int()

    override func viewDidLoad() {
        // get posts elements here 
        //posts.append(element).......
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

            return posts.count // 4counts 

    }

    func numberOfSections(in tableView: UITableView) -> Int {

        return 1
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
       // let cell = DetailMutiTableViewCell()
        let cell = tableView.dequeueReusableCell(withIdentifier: "DetailMutiTableViewCell", for: indexPath) as! DetailMutiTableViewCell

        nowRow = indexPath.row

        cell.post = posts[nowRow]
        cell.collectionView1.delegate = self
        cell.collectionView1.dataSource = self

        cell.collectionView1.reloadData()
        return cell
    }



    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return posts[nowRow].imageUrls.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MultiImagesCollectionViewCell", for: indexPath) as! MultiImagesCollectionViewCell

        let photoUrlString = posts[nowRow].imageUrls[indexPath.item] // ←error occured
            let photoUrl = URL(string: photoUrlString)
            cell.imageView1.sd_setImage(with: photoUrl)


        return cell
    }
}

editeditedit

您肯定已经发现,与 table 行中的 collectionView 交互不会触发 tableView 方法 tableView(_:didSelectRowAt:),并且 tableView.indexPathForSelectedRownil 因为没有选择行。您需要一种从 collectionView 映射到包含它的 indexPath.row 的方法。此信息在 tableViewCell 设置时已知。

Home2ViewController 添加字典,将 UICollectionView 映射到行 Int:

var collectionViewRow = [UICollectionView : Int]()

tableView(_:cellForRowAt:) 中添加您知道 rowcollectionView 的条目:

collectionViewRow[cell.collectionView1] = indexPath.row

然后,任何时候你有 collectionView,你可以查找它的行:

let row = collectionViewRow[collectionView]!

完整代码如下:

class Home2ViewController: UIViewController, UITableViewDataSource,  UITableViewDelegate, UICollectionViewDataSource, UICollectionViewDelegate {

    var posts = [Post]()
    var collectionViewRow = [UICollectionView : Int]()

    override func viewDidLoad() {
        // get posts elements here
        //posts.append(element).......
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        return posts.count // 4counts
    }

    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        // let cell = DetailMutiTableViewCell()
        let cell = tableView.dequeueReusableCell(withIdentifier: "DetailMutiTableViewCell", for: indexPath) as! DetailMutiTableViewCell

        collectionViewRow[cell.collectionView1] = indexPath.row

        cell.post = posts[indexPath.row]
        cell.collectionView1.delegate = self
        cell.collectionView1.dataSource = self

        cell.collectionView1.reloadData()
        return cell
    }

    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        let row = collectionViewRow[collectionView]!
        return posts[row].imageUrls.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MultiImagesCollectionViewCell", for: indexPath) as! MultiImagesCollectionViewCell

        let row = collectionViewRow[collectionView]!
        let photoUrlString = posts[row].imageUrls[indexPath.item] // ←error occured
        let photoUrl = URL(string: photoUrlString)
        cell.imageView1.sd_setImage(with: photoUrl)

        return cell
    }
}

备注:

  1. 字典查找的强制解包不会失败,因为 collectionView 会在那里。如果你想用 if let 展开它,你需要决定当你没有得到一行时要做什么(这不应该发生)。
  2. 如果您的 table 允许编辑(用户可以重新排列行的顺序或删除行),此方法可能会失败。如果您不支持编辑,那么这将正常工作。要支持编辑,您可以将字典更改为 [UICollectionView : UITableViewCell]。然后,给定一个 UICollectionView,您可以查找它的 cell,然后调用 let indexPath = tableView.indexPath(for: cell) 来获取 indexPath,然后您的行就是 indexPath.row