UITableView Mix of Static and Dynamic Cells?

I know you cannot mix Static and Dynamic cell types in a single UITableView but I couldn't think of a better way to describe my issue.

I have several predetermined cells with fixed content, I also have an unknown number of cells with dynamic content which sits in the middle. So I want to my table to look something like this:

Fixed
Fixed
Fixed
Dynamic
Dynamic
Dynamic
Dynamic
Dynamic
Fixed
Fixed

So how exactly do you recommend I approach this in my cellForRowAtIndexPath method?

Thanks.


Solution 1:

After struggled for 1 day, found best solution

Updated for Swift 4

for the case of the question:

  1. Set sections of the tableView to 3

enter image description here

  1. Add a empty tableview cell in the second section which you want to apply the dynamic cells, change identifier of the cell as WiFiTableViewCell

  2. create a new XIB file called WiFiTableViewCell

enter image description here

  1. register the Nib in the function ViewDidLoad in tableViewController

    tableView.register(UINib(nibName: "WiFiTableViewCell", bundle: nil), forCellReuseIdentifier: "WiFiTableViewCell")
    
  2. add the following code to use both dynamic and static cell

    override func numberOfSections(in tableView: UITableView) -> Int 
    {
        return 3
    }
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if section == 1 {
            return self.dataSource.count
            //the datasource of the dynamic section
        }
        return super.tableView(tableView, numberOfRowsInSection: section)
     }
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        if indexPath.section == 1 {
            let cell = tableView.dequeueReusableCell(withIdentifier: "WiFiTableViewCell") as! WiFiTableViewCell
            return cell
        }
        return super.tableView(tableView, cellForRowAt: indexPath)
    }
    
     override func tableView(_ tableView: UITableView, indentationLevelForRowAt indexPath: NSIndexPath) -> Int {
         if indexPath.section == 1 {
             let newIndexPath = IndexPath(row: 0, section: indexPath.section)
             return super.tableView(tableView, indentationLevelForRowAt: newIndexPath)
         }
         return super.tableView(tableView, indentationLevelForRowAt: indexPath)
     }
    
     override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
         if indexPath.section == 1 {
             return 44
         }
         return super.tableView(tableView, heightForRowAt: indexPath)
      }
    

Solution 2:

As you stated you can't mix static and dynamic cells. However, what you can do is break up the content into different data arrays that correspond to each group. Then break the table up into difference sections and load the data from the correct array in cellForRowAtIndexPath:.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellID = @"CELLID";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID forIndexPath:indexPath];

    switch (indexPath.section) {
        case 0:{
            cell.textLabel.text = self.arrayOfStaticThings1[indexPath.row];
        }break;

        case 1:{
            cell.textLabel.text = self.arrayOfDynamicThings[indexPath.row];
        }break;

        case 2:{
            cell.textLabel.text = self.arrayOfStaticThings2[indexPath.row];
        }break;

        default:
            break;
    }

    return cell;
}



- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    switch (section) {
        case 0:{
            return self.arrayOfStaticThings1.count;
        }break;

        case 1:{
            return self.arrayOfDynamicThings.count;
        }break;

        case 2:{
            return self.arrayOfStaticThings2.count;
        }break;

        default:
            return 0;
            break;
    }
}