The iOS UITableView left slide shows the delete button and its reuse of cell

  • 2020-05-17 06:36:57
  • OfStack

Edit mode for UITableView
Simple delete function of UITableView (delete button appears in the left slide)
First UITableView needs to go into edit mode. Implement the following method to get into edit mode even if no code is written:


- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{ }

When the Delete button is clicked, the above method will be called, so some logic of deletion operation can be implemented in this method, such as:

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
      // The first change model
    [self.books removeObjectAtIndex:indexPath.row];
      // After the update view
    [self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}

If you want to modify the text of the Delete button, you can implement the following proxy method:

- (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return @" delete ";
}

This way can quickly implement the system's own simple delete method, and when UITableView enter the edit mode (Delete button appears), continue to click cell will automatically cancel the edit mode, very convenient.

In some applications, you might see that when the user clicks a button, a red circle appears on the left side of cell in UITableView, one inside --, and when you click on this -- it slides left, and the Delete button appears. How do you do that?

UITableView has an editing property. If you set this property to YES, you will enter edit mode. Again, set it to NO and it exits.

In the example mentioned above, when the user clicks the button, it will enter the edit mode, and the default form of the edit mode is 1 red on the left -- and when the user clicks the button, the Delete button will appear. The above method is called again when the user clicks the Delete button.

So with that said, all you need to do is set editing to YES and implement the above method.

UITableViewCell reuse
If UITableViewCell is in the tableView:cellForRowAtIndexPath: method, like other class 1, use the following:


UITableViewCell *cell = [[UITableViewCell alloc] init];
cell.textLabel.text = @"hello";
...

This will display correctly, but the performance is questionable.

Apple actually helped us improve performance. If you wanted to display 200 rows of data, creating 200 cell at the same time would be very performance consuming and would not make much sense -- some of the cell would not be displayed at all.

Therefore, when UITableView is used, tableView:cellForRowAtIndexPath: method will be called only when cell is about to be displayed. That is to say, if there are 200 rows of data, cell will only be created that we can see, while cell will not be created for data that we cannot see.

For example, five cell (numbered 0-4) can be displayed simultaneously on the mobile phone screen. When the user slides up tableView, the sixth cell will appear, while the first cell has not disappeared, so six UITableViewCell will be created at this time. When the seventh cell appears, the first cell completely disappears from the screen, the UITableViewCell object is destroyed, and the seventh cell is created. Similarly, when a new cell appears, a new cell is created and the missing cell is destroyed.

You don't have to create 200 cell at the same time, but you can still have performance problems creating and destroying cell over and over again.

Apple offers a better way to reuse cell than to destroy it.

Every time a new cell appears (that is, when the tableView:cellForRowAtIndexPath: method is executed), instead of creating an cell directly, you should look in the buffer pool for a reusable cell, and if so, reuse this cell; If not, create an cell. So whether the data is 200 rows, 2,000 rows, or 20,000 rows, you're actually creating just the number of cell visible to the screen.

As in the above example, when the seventh cell is about to appear and the first cell disappears, the first cell is not destroyed, but placed in the buffer pool for reuse. At this point the seventh cell will first look in the buffer pool to see if there is a reusable cell, and when it finds one (that is, the first cell that disappeared), it will be reused instead of recreated. So one goes away, one goes away, and the next time you reuse this, you can make sure that you're creating a minimum number of cell, and you're still meeting your requirements.

Reuse of cell can be achieved using the following methods:

Use the code to create the new cell:


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString * const cellIdentifier = @"CellIdentifier";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    if (!cell) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
          cell.backgroundColor = [UIColor greenColor];
    }
    cell.textLabel.text = @"hello";     return cell;
}

Here are a few things to note:

When cell is nil and you need to create a new cell, you use the initWithStyle:reuseIdentifier: method instead of the init method. This is because you need to bind 1 identifier to create a new cell so that you can find the same reusable type when you reuse it. If the init method is used, identifier is not bound, so the corresponding reusable cell cannot be successfully found at the time of reuse.

In like 1 if (! In cell), that is, when creating cell, initialize a property that needs to be initialized only once, not outside of this parenthesis. These properties do not need to be set more than once because they are executed multiple times outside the parenthesis. Similarly, if different cell needs to set different properties or data, then it needs to be executed outside the parenthesis, because every time cell appears outside the parenthesis, it will be executed to ensure that different properties or data are corresponding to different cell. If the code that should have been set to different cell corresponding to different attributes is put in parentheses, the data will not be re-overwritten when the cell is reused, resulting in incorrect results and the problem of data redundancy in the morning.

Another way is to automatically create a new cell:


NSString * const cellIdentifier = @"CellIdentifier"; - (void)viewDidLoad
{
    [super viewDidLoad];     [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:cellIdentifier];
} - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];     cell.textLabel.text = @"hello";     return cell;
}

First you need to register class, which means you need to tell tableView, first go to the buffer pool and find out if there is a reusable cell, and if there is, take it and reuse it. If not, automatically generate one cell and bind it to reuse identifier, based on the UITableViewCell class registered previously.

This method saves us from having to manually create cell ourselves, but it has its drawbacks: the cell style that apple gave us, we can't use it except by default.

In the first method we manually create cell using initWithStyle: reuseIdentifier: we can pass in different style to create cell provided by apple, but this is not possible in the second method.

The second method is more often used when we customize Cell. While we can't use more of the system's native styles, we can first register our custom cell class (replace UITableViewCell with a custom Cell), and then still go to the buffer pool first to see if there is a reusable cell. If not, we can create cell and bind identifier based on the registered cell. Of course, when using dequeueReusableCellWithIdentifier:, you should also return a custom Cell type.

You can register not only Class, but also nib, which means you can register cell created through xib, just like the above method.

You can also set identifier of prototype cell directly through Storyboard. You can use cell directly in dequeueReusableCellWithIdentifier: without registering in advance or manually creating cell.


Related articles: