先看效果
ZZFoldCell.gif
源碼
https://github.com/guoxuzan/ZZFoldCell
原理分析
圖中的行政區(qū)域是樹形結(jié)構(gòu)蔓肯,但UITableView的Cell是隊列形式小压,展開與折疊效果靠UITableView的Cell插入刪除實現(xiàn)战授。
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView beginUpdates];
if (//要展開) {
//子節(jié)點成為兄弟節(jié)點
//insertRows
[tableView insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationFade];
}else {//要折疊
//兄弟節(jié)點變回子節(jié)點
//deleteRows
[tableView deleteRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationFade];
}
[tableView endUpdates];
}
樹的操作靠Model配合data實現(xiàn)
@interface ZZFoldCellModel : NSObject
@property(nonatomic,copy) NSString *text;//cell展示內(nèi)容
@property(nonatomic,copy) NSString *level;//節(jié)點級別
//...
@property(nonatomic,assign) NSUInteger belowCount;//子節(jié)點已經(jīng)轉(zhuǎn)為兄弟節(jié)點的個數(shù)
@property(nullable,nonatomic) ZZFoldCellModel *supermodel;//父節(jié)點
@property(nonatomic,strong) NSMutableArray<__kindof ZZFoldCellModel *> *submodels;//子節(jié)點
+ (instancetype)modelWithDic:(NSDictionary *)dic;//初始化
- (NSArray *)open;//返回并刪除子節(jié)點
- (void)closeWithSubmodels:(NSArray *)submodels;//插入子節(jié)點
@end
具體實現(xiàn)
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
ZZFoldCellModel *didSelectFoldCellModel = self.data[indexPath.row];
[tableView beginUpdates];
if (didSelectFoldCellModel.belowCount == 0) {
//Data
NSArray *submodels = [didSelectFoldCellModel open];
NSIndexSet *indexes = [NSIndexSet indexSetWithIndexesInRange:((NSRange){indexPath.row + 1,submodels.count})];
[self.data insertObjects:submodels atIndexes:indexes];
//Rows
NSMutableArray *indexPaths = [NSMutableArray new];
for (int i = 0; i < submodels.count; i++) {
NSIndexPath *insertIndexPath = [NSIndexPath indexPathForRow:(indexPath.row + 1 + i) inSection:indexPath.section];
[indexPaths addObject:insertIndexPath];
}
[tableView insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationFade];
}else {
//Data
NSArray *submodels = [self.data subarrayWithRange:((NSRange){indexPath.row + 1,didSelectFoldCellModel.belowCount})];
[didSelectFoldCellModel closeWithSubmodels:submodels];
[self.data removeObjectsInArray:submodels];
//Rows
NSMutableArray *indexPaths = [NSMutableArray new];
for (int i = 0; i < submodels.count; i++) {
NSIndexPath *insertIndexPath = [NSIndexPath indexPathForRow:(indexPath.row + 1 + i) inSection:indexPath.section];
[indexPaths addObject:insertIndexPath];
}
[tableView deleteRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationFade];
}
[tableView endUpdates];
}