Before this article, THE author has put the relevant code on GitHub and added CocoaPods support, welcome to download and view: STDTableView, below enter the topic:

To start with the background of this article, a company project required a dynamically edited form page, as shown in the following figure:

  • The cell must support keyboard input and verify the input validity.
  • The cell needs to be able to specify the data type to be entered and the data type to be submitted.
  • The cell supports various pop-up selectors (time selection, item selection, and linkage selection).
  • The cell should support push to the next interface for data selection.
  • Forms need to be able to dynamically add or remove items during editing;
  • The form must support mandatory and non-mandatory fields.
  • The form needs to support specifying non-editable entries;
  • Forms need to support initialization with data loaded back from the network; .

The tableView structure in previous projects has been unable to meet the needs of this type, especially for internal cell event processing, so the idea of encapsulating UITableView came into being, STDTableView was also born in this situation, Based on this library, the author perfectly realized the above requirements and implemented them into the company’s projects. STDTableView STDTableView STDTableView

It can be said that UITableView is one of the most commonly used components in iOS development. About its interface and basic usage methods, I believe everyone is already familiar with it. This article mainly discusses how to avoid viewController becoming bloated in the case of business explosion. And how to more elegant and concise implementation of UITableView related calls.

First of all, a brief list of daily development often encountered several situations:

  1. A list has multiple sections, each with a different cell structure;
  2. A list has only one section, but there are multiple cell structures in the section;
  3. You need to respond to click events inside the cell in the viewController;

If you are not careful, you will often write code in the following style:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = nil;

    if (indexPath.section == 0) {
        cell = xxx;
    } else if (indexPath.section == 1) {
        cell = xxx;
    } else {
        cell = xxx;
    }

    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.section == 0) {
        xxx
    } else if (indexPath.section == 1) {
        xxx
    } else {
        xxx
    }
}

Copy the code

A single cell type is ok, but if you need to add different types, or jump to different pages according to different rows, this pile of code will slowly grow, and finally may not want to maintain their own look!

So is there a way to optimize this problem? Let’s start with the following points:

  1. Create a dataAdapter class and store the cell data and basic configuration such as cellReuseIdentifier, cellHeight, cellType as the cell data source.
  2. Encapsulate the cell’s data configuration and selected callback, and then call cellForRowAtIndexPath and didSelectRowAtIndexPath with a method such as loadContent and selectedEvent;
  3. Remove the dataSource from the viewController;

So our code can look like this, and the viewController doesn’t need to rewrite the data source method every time:

// Independent data source
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    STDTableViewItem *item = [self itemAtIndexPath:indexPath];
    
    STDTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:item.cellReuseIdentifier];
        
    [cell loadContent];
    
    return cell;
}

// Delegate callback in viewController
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
	[(STDTableViewCell *)[tableView cellForRowAtIndexPath:indexPath] selectedEvent];
}
Copy the code

However, there is a problem with this approach, that is the way the dataAdapter is created, generally we request back data is directly parsed into the Model array, if the viewController directly explicit conversion is no doubt very unfriendly, which requires us to continue to do a layer of encapsulation!

Since then, we have been able to better solve the problems 1 and 2 proposed in the previous two points. We need to respond to the click event ‘inside the Cell in the viewController as follows:

  1. Add a delegate method for cell ‘tableViewCell: Event :’;
  2. Set the viewController as a delegate when the cell is initialized, and implement protocol methods in the viewController.
  3. Perform something like ‘[self.delegate tableViewCell:self Event :@(STDEditEventInputFinish)]’ in the corresponding event of the cell to tell the viewController what happened;

According to this idea of encapsulation, we have been able to achieve a good decoupling of UITableView and call simplification, and then is to do some structural optimization! According to this idea, THE author encapsulated a library STDTableView and attached relevant demo, support CocoaPods installation, welcome to download and view, if there is any problem, welcome to discuss or issue together!