CocoaPods trunk is moving to be read-only. Read more on the blog, there are 18 months to go.

RGArray 1.3.0

RGArray 1.3.0

Maintained by Renge.



RGArray 1.3.0

  • By
  • RengeRenge

RGArray

RGArray inherit NSMutableArray, which could make a callback for the change of internal elements (insert, delete, replace, sort), including a certain change position

Installation

Add via CocoaPods by adding this to your Podfile:

pod 'RGArray'

Usage

Import

#import <RGArray/RGArray.h>

RGArrayChangeDelegate

@interface ViewController () <UITableViewDataSource, UITableViewDelegate, RGArrayChangeDelegate>
@property (nonatomic, strong) RGArray <NSString *> *array;
@end
  
- (void)init {
  self.array = [RGArray arrayWithObjects:@"1", @"6", @"4", nil];
  [self.array addDelegate:self];
}

#pragma mark - RGArrayChangeDelegate

- (void)changeArray:(nonnull RGArray *)array change:(nonnull RGArrayChange *)change {
  NSLog(@"%@", change);
  [self.tableView beginUpdates];
  [self.tableView deleteRowsAtIndexPaths:change.deletionIndexPaths withRowAnimation:UITableViewRowAnimationAutomatic];
  [self.tableView insertRowsAtIndexPaths:change.insertionsIndexPaths withRowAnimation:UITableViewRowAnimationAutomatic];
  [self.tableView reloadRowsAtIndexPaths:change.modificationIndexPaths withRowAnimation:UITableViewRowAnimationAutomatic];
  [self.tableView endUpdates];
}

callback step-by-step

Sometimes, we cannot use "reloadRowsAtIndexPaths" to refresh the list, because when the list has a selected state, the selected state will be lost after refreshing.

At this time, you need to take out a specific cell for modification.

self.array.changeByStep = YES;
#pragma mark - RGArrayChangeDelegate

- (void)changeArray:(RGArray *)array change:(RGArrayChange *)change {
  NSLog(@"change: %@", change);
  if (change.deletions.count || change.insertions.count) {
    [self.tableView beginUpdates];
    [self.tableView deleteRowsAtIndexPaths:change.deletionIndexPaths withRowAnimation:UITableViewRowAnimationAutomatic];
    [self.tableView insertRowsAtIndexPaths:change.insertionsIndexPaths withRowAnimation:UITableViewRowAnimationAutomatic];
    [self.tableView endUpdates];
  } else {
    [change.modificationIndexPaths enumerateObjectsUsingBlock:^(NSIndexPath * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
      UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:obj];
      if (cell) {
        [self configCell:cell withObj:array[obj.row]];
      }
    }];
  }
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
  UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"TableViewCellID" forIndexPath:indexPath];
  NSString *obj = self.array[indexPath.row];
  [self configCell:cell withObj:obj];
  return cell;
}

- (void)configCell:(UITableViewCell *)cell withObj:(NSString *)obj {
  cell.textLabel.text = obj;
}

⚠️ In this case, if you don’t use stepwise Callback, it will cause some exceptions in the list.

Set Compare Rule For elements

  • set special rule for a array
[self.array setEqualRule:^BOOL(NSString * _Nonnull obj, NSString * _Nonnull other) {
	return [obj isEqualToString:other];
}];
[self.array setModifyRule:^BOOL(NSString * _Nonnull old, NSString * _Nonnull young) {
  return ![old isEqualToString:young];
}];
  • implement RGChangeProtocol for elements
#pragma mark - RGChangeProtocol

- (BOOL)rg_arrayObjIsEqual:(id)object {
    if ([object isKindOfClass:self.class]) {
        return [NSString rg_equalString:self.iotId toString:[object iotId]];
    }
    return NO;
}

- (BOOL)rg_arrayObjHasModification:(id)old {
    if ([old isKindOfClass:self.class]) {
        BOOL equal = self.status == [old status] &&
        [NSString rg_equalString:self.nickName toString:[old nickName]];
        return !equal;
    }
    return NO;
}

Demo

  • Simple Case

    1

  • Complex Case

    generate a new array randomly

    2