UITableViewDiffableDataSource简单使用(Objective-C版本)

前言:

UITableViewDiffableDataSource仅支持iOS 13以上系统调用,如果用在实际项目开发中请注意一下。个人建议还是使用UITableViewDataSource为好。

UITableViewDiffableDataSource继承自NSObject,我们使用时一般创建一个继承自它的新类,例如MYTableViewDiffableDataSource。在这个类中你可以实现UITableViewDataSource的一些代理方法,以便扩展更多的功能。

简单API介绍:

1、调用appendSectionsWithIdentifiers添加section:

- (void)appendSectionsWithIdentifiers:(NSArray*)sectionIdentifiers;

2、调用appendItemsWithIdentifiers在最后一个section中添加item数据:

- (void)appendItemsWithIdentifiers:(NSArray<ItemIdentifierType>*)identifiers;

3、在指定的section中添加item数据:

- (void)appendItemsWithIdentifiers:(NSArray<ItemIdentifierType>*)identifiers intoSectionWithIdentifier:(SectionIdentifierType)sectionIdentifier

4、删除指定的item数据:

- (void)deleteItemsWithIdentifiers:(NSArray<ItemIdentifierType>*)identifiers;

5、删除所有数据:

- (void)deleteAllItems;

………………太多了,这里省略,接下来是关键……

n、将以上改动(添加、删除、移动……)应用到tableview中:

- (void)applySnapshot:(NSDiffableDataSourceSnapshot<SectionIdentifierType,ItemIdentifierType>*)snapshot animatingDifferences:(BOOL)animatingDifferences;

话不多说,上代码!完整demo项目地址在文章末尾

效果图:

           

demo代码:(注释很重要)


#import "MasterViewController.h"
#import "DetailViewController.h"
#import "MYTableViewDiffableDataSource.h"

@interface MasterViewController ()

@property NSMutableArray *objects;

@property (nonatomic) MYTableViewDiffableDataSource *datasource;   //创建自己的类以便实现更多的UITableViewDataSource代理方法

@end

@implementation MasterViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.navigationItem.leftBarButtonItem = self.editButtonItem;

    UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(insertNewObject:)];
    self.navigationItem.rightBarButtonItem = addButton;
    self.detailViewController = (DetailViewController *)[[self.splitViewController.viewControllers lastObject] topViewController];
    
    //指定新的代理
    self.tableView.dataSource = self.datasource;
}

- (UITableViewDiffableDataSource *)datasource {
    
    if (!_datasource) {
        _datasource = [[MYTableViewDiffableDataSource alloc] initWithTableView:self.tableView cellProvider:^UITableViewCell * _Nullable(UITableView * _Nonnull tableView, NSIndexPath * _Nonnull indexPath, id _Nonnull date) {
            //
            
            UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];

            NSDate *object = date;
            cell.textLabel.text = [object description];
            return cell;
            
        }];
    }
    return _datasource;
}


- (void)viewWillAppear:(BOOL)animated {
    self.clearsSelectionOnViewWillAppear = self.splitViewController.isCollapsed;
    [super viewWillAppear:animated];
}


- (void)insertNewObject:(id)sender {
    
    NSDiffableDataSourceSnapshot *snapshot = self.datasource.snapshot;
    
    //不可以每次都创建新的snapshot⚠️,否则数据都是新的!
    //NSDiffableDataSourceSnapshot *snapshot = [[NSDiffableDataSourceSnapshot alloc] init];
    
    //数据太多了清空一下
    if (snapshot.numberOfItems >= 10) {
        [snapshot deleteAllItems];
        [self.datasource applySnapshot:snapshot animatingDifferences:YES completion:^{
        }];
        return;
    }
    
    //必须先创建Section才可以插入数据
    if(snapshot.numberOfSections==0)
    {
        [snapshot appendSectionsWithIdentifiers:@[@"1"]];   //SectionIdentifierType不可以重复⚠️
    }else
    {
        if (snapshot.numberOfItems == 5) {
            [snapshot appendSectionsWithIdentifiers:@[@"2"]];  //根据需求添加更多的Section
        }
    }
    
    //往Section中添加数据,默认添加到最后一个Section中
    [snapshot appendItemsWithIdentifiers:@[[NSDate date]]];  //ItemIdentifierType也不可以重复⚠️
    
    //往指定Section中添加数据
    //[snapshot appendItemsWithIdentifiers:@[[NSDate date]] intoSectionWithIdentifier:@"2"];
    
    [self.datasource applySnapshot:snapshot animatingDifferences:YES completion:^{
        //
    }];
}

#pragma mark - Segues

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    if ([[segue identifier] isEqualToString:@"showDetail"]) {
        NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
        NSDate *object = [self.datasource itemIdentifierForIndexPath:indexPath];
        DetailViewController *controller = (DetailViewController *)[[segue destinationViewController] topViewController];
        controller.detailItem = object;
        controller.navigationItem.leftBarButtonItem = self.splitViewController.displayModeButtonItem;
        controller.navigationItem.leftItemsSupplementBackButton = YES;
        self.detailViewController = controller;
    }
}

//⚠️不可以再实现以下方法⚠️
//#pragma mark - Table View
//
//- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
//    return 1;
//}
//
//
//- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
//    return self.objects.count;
//}
//
//
//- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
//
//    NSDate *object = self.objects[indexPath.row];
//    cell.textLabel.text = [object description];
//    return cell;
//}


@end
@interface MYTableViewDiffableDataSource : UITableViewDiffableDataSource

@end


#import "MYTableViewDiffableDataSource.h"

@implementation MYTableViewDiffableDataSource


- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
    // Return NO if you do not want the specified item to be editable.
    return YES;
}

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        
        id item = [self itemIdentifierForIndexPath:indexPath];
        
        //这里注意一下,每次调用self.snapshot都会创建新的对象⚠️⚠️⚠️
        NSDiffableDataSourceSnapshot *snapshot = self.snapshot;
        NSDiffableDataSourceSnapshot *snapshot1 = self.snapshot;   //测试⚠️
        NSDiffableDataSourceSnapshot *snapshot2 = self.snapshot;   //测试⚠️
        NSDiffableDataSourceSnapshot *snapshot3 = self.snapshot;   //测试⚠️
        
        //删除的时候不用指定Section,因为每一个item都是唯一的
        [snapshot deleteItemsWithIdentifiers:@[item]];

        [self applySnapshot:snapshot animatingDifferences:YES completion:^{
            //
        }];
        
        //不可以再使用tableview的方法删除⚠️⚠️⚠️
        //[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
        
    } else if (editingStyle == UITableViewCellEditingStyleInsert) {
        // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view.
    }
}

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    return 20;
}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
    return [NSString stringWithFormat:@"%ld",section];
}

@end

项目地址:GitHub

猜你喜欢

转载自blog.csdn.net/xuexixiaoshizhe/article/details/106619271