Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
715 views
in Technique[技术] by (71.8m points)

swift - How to deal with dynamic Sections and Rows in iOS UITableView

My issue

When I deal with UITableView, I basically have an Array table_data with my sections and rows.

[
   {
      title : "section A title",
      rows: [
          {data: row_1_data},
          {data: row_2_data}
      ]
   },
   {
      title : "section B title",
      rows: [
          {data: row_1_data},
          {data: row_2_data}
      ]
   },
]

I use heightForHeaderInSection, cellForRowAtindexPath, titleForHeaderInSection, didSelectRowAtindexPath methods like this

 if indexPath.section == 0 {
        //section A
        if indexPath.row == 0 {
             //do something with table_data[0]["rows"][0]["data"]
        }
        elesif indexPath.row == 1 {
             //do something else
        }
 }
 if indexPath.section == 1 {
      //do something for section B
 }

Working with numbers 0, 1, etc becomes a headache, when my table_data array is dynamic. Dynamic means, that some sections or rows can have different positions or don't exist at all.

For example, I remove A section and my array is

[
   {
      title : "section B title",
      rows: [
          {data: row_1_data},
          {data: row_2_data}
      ]
   }
]

I do like this

self.section_A_position = 0
self.section_B_position = 1
func afterRemoveSectionA() {
    section_A_position = -999
    section_B_position = section_B_position - 1
    //write here another new sections for -1 
}

Add another section C as 0 element

self.section_C_position = -999
func afterAddSectionC() {
   section_C_position = 0
   section_A_position = section_A_position + 1
   section_B_position = section_B_position + 1
}

And then use section_positions in functions

 if indexPath.section == section_A_position {
        //section A
        if indexPath.row == 0 {
             //do something with table_data[0]["rows"][0]["data"]
        }
        elesif indexPath.row == 1 {
             //do something else
        }
 }
 if indexPath.section == section_B_position {
      //do something for section B
 }

It looks pretty simple, but when I have many sections and many cases to hide or move it in array, it becomes difficult to control and add new types of sections. Sometimes I create section_positions_map array to store it together and make +1, -1 operation in loop. But it doesn't help it is still difficult to organize it in every TableViewController, when I need this behavior.

Question

Do you know any approaches or frameworks that make this part easier?

My Ideas

  1. Add type property to my Dictionaries
{
  title : "section A title",
  rows: [
      {data: row_1_data},
      {data: row_2_data}
  ]
  type : "section_a"
}

and check if table_data[0]["type"] == "section_a" (or use enum to collect types)

  1. Subclass my Dictionary and check

if table_data[0] is SubClassSectionA

but both of them looks ugly for me.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

An approach I use when creating a table where I know all the possible sections is with enums. You create an enum for each of the possible section types:

enum SectionTypes { case sectionA, sectionB, sectionC }

And then create a variable to hold the sections:

var sections: [SectionTypes]

When you have your data ready then you populate sections with the sections that needs to be displayed. I usually also make a method to help get the section:

func getSection(forSection: Int) -> SectionTypes {
        return sections[forSection]
    }

With this in place you can start implementing the common DataSource delegate methods:

func numberOfSections(in collectionView: UICollectionView) -> Int {
    return sections.count
}

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    switch getSection(forSection: section) {
    case .sectionA:
        return 0 //Add the code to get the count of rows for this section
    case .sectionB:
        return 0
    default:
        return 0
    }
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    switch getSection(forSection: indexPath.section) {
    case .sectionA:
        //Get section A cell type and format as your need
    //etc
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...