简体   繁体   English

在每个单元格都包含表格视图的表格视图中选择新单元格时,无法取消选择先前选择的单元格

[英]Can’t deselect previously selected cell when a new one is selected in a tableview where each cell contains tableview

I have a tableview, where each cell is a custom tableview cell.我有一个表格视图,其中每个单元格都是一个自定义表格视图单元格。 That custom tableview cell contains a tableview and a label.该自定义表格视图单元格包含一个表格视图和一个 label。 Lets say, the outer tableview is called MainTableView.可以说,外部 tableview 称为 MainTableView。 Each cell of MainTableView consists another tableview. MainTableView 的每个单元格都包含另一个 tableview。 The problem is, when I select inner tableview cell one by one the previously selected cell is not get deselected.In first image I have selected cell contains text “Two”.问题是,当我 select 内部 tableview 单元格一个接一个时,先前选择的单元格没有被取消选择。在第一张图像中,我选择的单元格包含文本“Two”。 Then In the second image I have selected cell contains text “Five” but perviously selected cell “Two” still in selection mode.然后在第二张图片中,我选择的单元格包含文本“五”,但之前选择的单元格“二”仍处于选择模式。 I want to deselect the previous cell when select a new one.我想在 select 一个新的单元格时取消选择上一个单元格。

第一张图片 第二张图片

I have tried我努力了

tableView.deselectRow(at: IndexPath, animated: Bool)

this method inside didSelectRowAt in custom tableviewcell class but it didn't serve the purpose because the previous indexPath is from seperate tableview.此方法在自定义 tableviewcell class 中的 didSelectRowAt 中,但它没有达到目的,因为先前的 indexPath 来自单独的 tableview。 So, how can I deselect the previous one?那么,如何取消选择上一个呢?

to get the correct inner tableView,获得正确的内部tableView,

Firstly , you should record the outside tableView's cell indexPath, which cell the inner tableView is in.首先,您应该记录外部 tableView 的单元格 indexPath,内部 tableView 所在的单元格。

So your should record two indexPathes所以你应该记录两个 indexPathes

var selectionRowInfo: (lastOutsideIP: IndexPath?, lastInnerIP: IndexPath?)

Secondly , you get the correct tableView, via the outsideTableView.其次,您通过outsideTableView 获得正确的tableView。

if the inner table is visible, you shall handle it immediately.如果内表可见,则应立即处理。 through outTableView.indexPathsForVisibleRows通过outTableView.indexPathsForVisibleRows

the else condition , you need not handle it. else 条件,你不需要处理它。 The tableView reuse mechanism will refresh its state. tableView重用机制会刷新它的state。

    // pseudo code.


    if let lastOut = lastOutsideIP, let visibleRows = outTableView.indexPathsForVisibleRows, visibleRows.contains(lastOut){
        let cell = tableView.cellForRow(at: lastOut) as! YourCell
        // get the correct inner tableView via the cell
    }

Because the inner tableViews are not related to each other.因为内部 tableViews 彼此不相关。 Select the cell of table one, will not affect the selection of cell of table two. Select 表一的单元格,不会影响表二的单元格的选择。

So your should build the connection manually.所以你应该手动建立连接。

Use a property to store the state var lastIndexPath: IndexPath?使用属性存储 state var lastIndexPath: IndexPath? , ,

then every time select a indexPath,然后每次 select 一个 indexPath,

  // pseudo code.
  if let last = lastIndexPath{
        tableView.deselectRow(at: last, animated: true) 
  }

Please notice that, you should find the correct inner tableView, which has the lastIndexPath请注意,您应该找到正确的内部 tableView,它具有lastIndexPath

The previous answer is along the right lines but has a flaw - it cannot distinguish between tableViews, which is the most important part.上一个答案是正确的,但有一个缺陷 - 它无法区分 tableViews,这是最重要的部分。 Also if the tableViews have different numbers of rows, it risks trying to access a row that doesn't exist and causing a crash.此外,如果 tableViews 具有不同数量的行,则可能会尝试访问不存在的行并导致崩溃。

To track the selected row in two tableViews ( tv1 & tv2 ) you'll need to hold the selected row in each:要在两个 tableViews ( tv1 & tv2 ) 中跟踪选定的行,您需要在每个表中保留选定的行:

var tv1, tv2: UITableView!
var lastRowForTV1, lastRowForTV2: IndexPath?

and then respond to selections by identifying the tableView being used and adjusting the other (this assumes the two tableViews use the same datasource/delegate)然后通过识别正在使用的 tableView 并调整另一个来响应选择(这假设两个 tableViews 使用相同的数据源/委托)

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
      if tableView === tv1 {
         lastRowForTV1 = indexPath
         if let last = lastRowForTV2 {
            tv2.deselectRow(at: last, animated: true)
            lastRowForTV2 = nil
         }
      } else if tableView === tv2 {
         lastRowForTV2 = indexPath
         if let last = lastRowForTV1 {
            tv1.deselectRow(at: last, animated: true)
            lastRowForTV1 = nil
         }
      }
   }

I have solved the problem by using the idea of first answer given by dengApro.我通过使用dengApro给出的第一个答案的想法解决了这个问题。 The idea was to find the correct inner table which contains the previously selected cell.这个想法是找到包含先前选择的单元格的正确内表。 I have two files one is ViewController.swift that contains the outer tableview MainTableView.我有两个文件,一个是 ViewController.swift,其中包含外部 tableview MainTableView。 Another one is CustomTableViewCell.swift with CustomTableViewCell.xib that contains the custom cell with tableview.另一个是 CustomTableViewCell.swift 和 CustomTableViewCell.xib,其中包含带有表格视图的自定义单元格。

fileprivate var lastSelectedInnerTableView : Int = -1
fileprivate var lastSelectedRow: Int = -1
fileprivate var tableViewList :[UITableView] = []

I have added these 3 variables in CustomTableViewCell.swift file outside the class CustomTableViewCell.我在 class CustomTableViewCell 之外的 CustomTableViewCell.swift 文件中添加了这 3 个变量。 lastSelectedSection, lastSelectedRow these 2 variable are used to keep track of the last selected inner tableview (lastSelectedInnerTableView) and the last selected cell of that inner tableView (lastSelectedRow). lastSelectedSection、lastSelectedRow 这两个变量用于跟踪最后选择的内部表格视图(lastSelectedInnerTableView)和该内部表格视图的最后选择的单元格(lastSelectedRow)。 tableViewList variable is used to keep the Inner tableView. tableViewList 变量用于保存 Inner tableView。 Inside awakeFromNib() I have append the created inner tableviews.在 awakeFromNib() 里面我有 append 创建的内部表视图。

override func awakeFromNib() {
    super.awakeFromNib()
    self.tableView.delegate = self
    self.tableView.dataSource = self
    self.tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
    tableViewList.append(self.tableView) // append the created inner tableviews
}

Then inside didSelectRowAt I have deselect the previous one:然后在 didSelectRowAt 里面我取消了前一个:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    if lastSelectedInnerTableView != -1 && lastSelectedRow != -1{
        self.oldIndexPath.section = 0
        self.oldIndexPath.row = lastSelectedRow
        tableViewList[lastSelectedInnerTableView].deselectRow(at: self.oldIndexPath, animated: true)
    }

    lastSelectedInnerTableView = self.innerTableId
    lastSelectedRow = indexPath.row
}

In ViewController.swift I have set innerTableId inside cellForRowAt在 ViewController.swift 我在 cellForRowAt 中设置了 innerTableId

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let customCell: CustomTableViewCell = self.tableView.dequeueReusableCell(withIdentifier: "customCell") as! CustomTableViewCell
    customCell.innerTableId = indexPath.row
    customCell.customCellActionDelegate = self

    return customCell
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM