Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why it needs tableView(_:indentationLevelForRowAt:) when Inserting cell into a table view with static cells

Background

The story is come from the second example of the book IOS apprentice (Ed. 6 2016)

A UItableView with two section is created. In storyboard the following content had been designed: section 0 has one row fulfilled with one static cell, section 1 has two row full filled with two static cell.

What to achieve

When tap the last row of section 1 (ie, the dueDate row in picture A) a new cell with a UIDatePicker will be inserted into the tableView (please see picture B)

How does the author solve the problem

A UITableViewCell filled with a UIDatePicker is added in to the scene dock in storyBoard (please see picture C), the new tableCell will be added into the table when dueDate row is tapped

Table view with static cells does not have a data source and therefore does not use the function like “cellForRowAt”. In order to insert this cell into the table the following data source functions had been overridden

tableView(_:numberOfRowsInSection:) 
tableView(_:cellForRowAt:)
tableView(_:heightForRowAt:)
tableView(_:indentationLevelForRowAt:)

Problem

the function tableView(_:indentationLevelForRowAt:) really confuse me a lot! And here is the full code

  override func tableView(_ tableView: UITableView, indentationLevelForRowAt indexPath: IndexPath) -> Int {
    var newIndexPath = indexPath
    if indexPath.section == 1 && indexPath.row == 2 {
      newIndexPath = IndexPath(row: 0, section: indexPath.section)
    }
    return super.tableView(tableView, indentationLevelForRowAt: newIndexPath)
  }

Question

What is the meaning of this function? What's the purpose of it? I've read the document, but I didn't get much information.

When the third row/datePicker cell is inserted (indexPath.section == 1 && indexPath.row == 2) why the function will indent the first row newIndexPath = IndexPath(row: 0, section: indexPath.section) ?

enter image description here

like image 429
SLN Avatar asked Sep 07 '25 07:09

SLN


1 Answers

Implementing tableView(_:indentationLevelForRowAt:) allows you to display the table rows in a hierarchal / tree-view type format. As in:

Level 1
  Sub-Level 1a
  Sub-Level 1b
Level 2
  Sub-Level 2a
    Sub-sub-level 2aa
    Sub-sub-level 2ab
etc...

Commonly, one might use:

override func tableView(_ tableView: UITableView, indentationLevelForRowAt indexPath: IndexPath) -> Int {
    if let myObj = myData[indexPath.row] as? MyObject {
        return myObj.myIndentLevel
    }
    return 0
}

For the example you present, without reading the book...

It would appear the author decided that the new row (2) that contains the UIDatePicker should have the same indent level as the first row (0) in the section. If it's not the row 2, then return the default / current indentation level.

Although, the intent of

var newIndexPath = indexPath
if indexPath.section == 1 && indexPath.row == 2 {
  newIndexPath = IndexPath(row: 0, section: indexPath.section)
}
return super.tableView(tableView, indentationLevelForRowAt: newIndexPath)

might seem a little more obvious / clear with

  newIndexPath = IndexPath(row: 0, section: 1)

since it is already limiting this to section == 1.

like image 146
DonMag Avatar answered Sep 10 '25 00:09

DonMag