简体   繁体   中英

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. Lets say, the outer tableview is called MainTableView. Each cell of MainTableView consists another 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”. 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.

第一张图片 第二张图片

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. So, how can I deselect the previous one?

to get the correct inner tableView,

Firstly , you should record the outside tableView's cell indexPath, which cell the inner tableView is in.

So your should record two indexPathes

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

Secondly , you get the correct tableView, via the outsideTableView.

if the inner table is visible, you shall handle it immediately. through outTableView.indexPathsForVisibleRows

the else condition , you need not handle it. The tableView reuse mechanism will refresh its 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. Select the cell of table one, will not affect the selection of cell of table two.

So your should build the connection manually.

Use a property to store the state var lastIndexPath: IndexPath? ,

then every time select a 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

The previous answer is along the right lines but has a flaw - it cannot distinguish between tableViews, which is the most important part. Also if the tableViews have different numbers of rows, it risks trying to access a row that doesn't exist and causing a crash.

To track the selected row in two tableViews ( tv1 & tv2 ) you'll need to hold the selected row in each:

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)

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. 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. Another one is CustomTableViewCell.swift with CustomTableViewCell.xib that contains the custom cell with tableview.

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. 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). tableViewList variable is used to keep the Inner tableView. Inside awakeFromNib() I have append the created inner tableviews.

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:

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

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
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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