【问题标题】:How can I figure out which tableView Cell is selected when collectionview is scrolled horizontally水平滚动collectionview时如何确定选择了哪个tableView Cell
【发布时间】:2018-05-19 23:52:26
【问题描述】:

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

编辑编辑

【问题讨论】:

  • 手动将其存储在您的视图控制器中
  • indexPathForSelectedRowUITableView 属性怎么样?还是实现UITableViewDelegate协议的选择方法?
  • @McNight,与collectionView 交互不会选择包含它的tableView 单元格,所以indexPathForSelectedRownil 并且tableView(_:didSelectRowAt:) 不会被调用。

标签: ios swift swift3 tableview collectionview


【解决方案1】:

正如您毫无疑问地发现的那样,与表行中的 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. 如果您的表允许编辑(用户可以重新排列行的顺序或删除行),此方法可能会失败。如果您不支持编辑,那么这将正常工作。要支持编辑,您可以将字典更改为[UICollectionView : UITableViewCell]。然后,给定一个UICollectionView,您可以查找它的cell,然后调用let indexPath = tableView.indexPath(for: cell) 来获取indexPath,然后您的行就是indexPath.row

【讨论】:

  • 非常感谢。有效!我真的很感激。
  • 投反对票的人,你投反对票的理由是什么?如果没有反馈,我无法解决您的问题/疑虑。
  • 对不起,我不小心弄错了。我正在寻找如何支持您的问题。我一定会解决的。
  • 我创建了两个新帐户并两次投票赞成您的答案。我希望它有效。我是 stackOverflow 的新手。当我寻找如何标记最佳答案时,我错误地点击了投票。对不起,我向你道歉。
  • @kou,我很欣赏这种情绪,但你不是反对者。您没有足够的声望来支持或反对投票。其他人投了反对票。请不要在 Stack Overflow 上使用多个帐户。这是禁止的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-13
  • 1970-01-01
  • 2020-10-08
相关资源
最近更新 更多