0
点赞
收藏
分享

微信扫一扫

Sagit.Framework For IOS 自动布局教程:

前言:

框架对于UITableView、UITableViewCell 封装了不少功能,下面开始介绍。

1、UITableView 基本定义。

 

@interface UITableView(ST)

#pragma mark 核心扩展
typedef void(^OnAddTableCell)(UITableViewCell *cell,NSIndexPath *indexPath);
typedef BOOL(^OnDelTableCell)(UITableViewCell *cell,NSIndexPath *indexPath);
typedef void(^OnAddTableCellAction)(STUITableViewCellAction *cellAction, NSIndexPath *indexPath);
typedef void(^OnAddTableSectionHeaderView)(UIView *sectionHeaderView,NSInteger section);

typedef void(^OnAddTableSectionFooterView)(UIView *sectionFooterView,NSInteger section);

typedef void(^OnAfterTableReloadData)(UITableView *tableView);

//!用于为Table追加每一行的Cell
@property (nonatomic,copy) OnAddTableCell addCell;
//!用于为Table追加每一行的Cell的滑动菜单
@property (nonatomic,copy) OnAddTableCellAction addCellAction;
//!用于为Table追加每一组Section的标题View
@property (nonatomic,copy) OnAddTableSectionHeaderView addSectionHeaderView;

//!用于为Table追加每一组Section的Bottom View
@property (nonatomic,copy) OnAddTableSectionFooterView addSectionFooterView;

//!用于为Table移除行的Cell
@property (nonatomic,copy) OnDelTableCell delCell;
//!用于为Table reloadData 加载完数据后触发
@property (nonatomic,copy) OnAfterTableReloadData afterReload;
//!获取Table的数据源
@property (nonatomic,strong) NSMutableArray<id> *source;
//!设置Table的数据源
-(UITableView*)source:(NSMutableArray<id> *)dataSource;
//!存档所有Cell的高度(由系统控制)[存档格式为:section key,[row Array]]
@property (readonly,nonatomic,retain) NSMutableDictionary *heightForCells;

//!是否重用Cell(默认Yes)
-(BOOL)reuseCell;
-(BOOL)reuseCell:(BOOL)yesNo;
//!是否自动控制Table的高度
-(BOOL)autoHeight;
//!设置是否自动控制Table的高度
-(UITableView*)autoHeight:(BOOL)yesNo;
//!获取默认的UITableViewCellStyle
-(UITableViewCellStyle)cellStyle;
//!设置默认的UITableViewCellStyle
-(UITableView*)cellStyle:(UITableViewCellStyle)style;
//!获取是否允许编辑【删除】属性
-(BOOL)allowEdit;
//!设置是否允许编辑【删除】
-(UITableView*)allowEdit:(BOOL)yesNo;
//!移除数据源和数据行(并重新计算且刷新高度)
-(UITableView*)afterDelCell:(NSIndexPath*)indexPath;
#pragma mark 扩展属性
-(UITableView*)scrollEnabled:(BOOL)yesNo;
//!分组数(默认1)
-(UITableView*)sectionCount:(NSInteger)count;
//!每个Section的num数:参数可以传递:@[@"1",@"2",@"2",@"1"] 或者:@"1,2,2,1"
-(UITableView*)rowCountInSections:(id)nums;
@end

2、UITableViewCell 基本定义:

@interface UITableViewCell(ST)
//!获取当前所在的table,(weak,不能造成双strong引用)
@property (readonly,nonatomic,weak) UITableView *table;
//!获取Cell的数据源
@property (nonatomic,strong) id source;
//!Cell是否重用的Cell,如果是,就不要再添加子控制,避免重复添加。
//@property (readonly,nonatomic,assign) BOOL isReused;
//!设置Cell的数据源
-(UITableViewCell *)source:(id)dataSource;
//!创建或复用Cell
+ (instancetype)reuseCell:(UITableView *)tableView index:(NSIndexPath *)index;
//!获取Cell所在的行数
-(NSIndexPath*)indexPath;
-(UITableViewCell*)indexPath:(NSIndexPath*)indexPath;
//!获取是否允许删除属性
-(BOOL)allowDelete;
//!设置是否允许删除
-(UITableView*)allowDelete:(BOOL)yesNo;
//!数据源中的第一个字段,系统自动设置
-(NSString*)firstValue;
-(UITableViewCell*)firstValue:(NSString*)value;
//当Cell的高度在绑定后,需要动态根据子内容高度变化,再次刷新高度时使用。
-(UITableViewCell*)resetHeightCache;
#pragma mark 扩展属性
-(UITableViewCell*)accessoryType:(UITableViewCellAccessoryType)type;
-(UITableViewCell*)selectionStyle:(UITableViewCellSelectionStyle)style;

#pragma mark 扩展
//!获取Cell的滑动菜单项。
@property (nonatomic,strong) STUITableViewCellAction *action;

@end

UITableView 基本用法示例一:

[[[[[sagit addTableView:nil] autoHeight:YES]  width:610] toCenter] block:^(UITableView* table)
{
[table relate:TopBottom v:60 v2:60];
[table backgroundColor:ColorClear];
table.backgroundView=[[[[UIImageView new] image:@"answer_bg_rank"]stretch] width:1 height:1];
table.separatorColor = [ColorWhite alpha:0.2];
table.separatorInset=UIEdgeInsetsMake(0,26, 0, 26);
table.addCell = ^(UITableViewCell *cell, NSIndexPath *indexPath)
{
[cell width:1 height:140]; // 1 代表 100% <=1 被处理成百分比。=UITableViewCellAccessoryNone;
cell.backgroundColor=ColorClear;


//数据
AnswerUserRankModel *model=[[AnswerUserRankModel new] initWithObject:cell.source];
NSString *score=[[@(model.Score) stringValue] append:@" 分"];

[cell.contentView block:^(UIView* view)
{
[view width:1 height:1];
if(indexPath.row!=table.source.count-1)
{
[[[[view addLine:nil color:@"#81F0D7"] width:2 height:30]y:140-15] relate:Right v:26];
[[[[view addLine:nil color:@"#81F0D7"] width:30 height:2] y:140] relate:Right v:26];
}

[view addLabel:nil text:STNumString(model.Rank) font:30 color:ColorWhite];
[[STLastView x:50] toCenter:Y];

[[[[view addImageView:nil] url:model.PhotoPath] width:80 height:80] corner:YES];
[[STLastView x:122] toCenter:Y];

[[[[view addLabel:nil text:model.NickName font:30 color:@"#FB8107"] onRight:STPreView x:42] toCenter:Y] width:72*2];
[[[view addImageView:nil img:@"answer_bg_rankscore"] width:196 height:20] block:^(UIImageView* scoreView)
{
[[scoreView x:192*2] toCenter:Y];
//[[scoreView relate:Right v:160] toCenter:Y];
[[scoreView addLabel:nil text:score font:30 color:@"#81F0D7"] toCenter];
//[scoreView stSizeToFit];
}];
[view onClick:^(id view)
{
[self stPush:[STNew(@"User") key:@"uid" value:model.UserID]];
}];
}];

};
}];

效果:

Sagit.Framework For IOS 自动布局教程:_数据源

 

 

UITableView 基本用法示例二:

@"tableView" style:UITableViewStyleGrouped] autoHeight:YES] onBottom:STPreView y:20]  block:nil on:^(UITableView* table) {
[table reuseCell:NO];
table.addCell = ^(UITableViewCell *cell, NSIndexPath *indexPath)
{
NSString *name=cell.source[@"name"];
NSString *title=cell.source[@"title"];
NSString *holder=cell.source[@"holder"];
if(holder==nil){holder=title;}
NSString *pick=cell.source[@"pick"];
NSString *maxLength=cell.source[@"maxLength"];

[[[cell.contentView addLabel:nil text:title font:30] relate:Left v:50] toCenter:Y];//label是固定的。
UIView *textView;

if([title isEqualToString:@"简介"])
{
textView=[[[[[cell.contentView addTextView:name placeholder:holder font:30] maxRow:3] maxLength:100]
textAlignment:NSTextAlignmentLeft] height:0.8];
UIEdgeInsets inset=textView.asTextView.textContainerInset;
inset.left-=5;
textView.asTextView.textContainerInset=inset;
}
else
{
textView=[[cell.contentView addTextField:name placeholder:holder font:30] height:0.8];
if(maxLength!=nil)
{
[STLastTextField maxLength:[maxLength integerValue]];
}
}
[[[textView onRight:STPreView x:50] relate:Right v:0] toCenter:Y];

if(pick==nil)
{
cell.accessoryType=UITableViewCellAccessoryNone;
}
else
{
[[STLastView addClick:@"pick"] key:@"pick" value:pick];
}
};
table.afterReload = ^(UITableView *tableView)
{
if(!self.hasLoaded)
{
self.hasLoaded=YES;
[self setToAll:Sagit.Global.User.user];
}
};

}];

效果:

Sagit.Framework For IOS 自动布局教程:_git_02

 

数据源设置:

-(void)initData
{
[super initData];//加载子UI的数据。
UITableView *table=STFirstTable;
table.source=@[@{@"title":@"姓名",@"name":@"NickName",@"maxLength":@"15"},
@{@"title":@"简介",@"name":@"Description",@"holder":@"请简单介绍一下自己!"},
@{@"title":@"公司",@"name":@"Company",@"holder":@"所在公司!",@"maxLength":@"20"},
@{@"title":@"年龄",@"name":@"Age",@"pick":@"年龄"},
@{@"title":@"学历",@"name":@"Edu",@"pick":@"学历"},
@{@"title":@"身高",@"name":@"Height",@"pick":@"身高"},
@{@"title":@"星座",@"name":@"Constellation",@"pick":@"星座"},
@{@"title":@"婚姻",@"name":@"MarrStatus",@"pick":@"婚姻"},
@{@"title":@"职业",@"name":@"Profession",@"pick":@"职业"},
@{@"title":@"收入",@"name":@"Wages",@"pick":@"月薪"}];

[[table sectionCount:2] rowCountInSections:@"3,7"];
//table.tableHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f,1, 0.01f)];
table.sectionFooterHeight=0.2;
// table.tableFooterView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f,1, 1.0f)];
//self.automaticallyAdjustsScrollViewInsets = NO;
[table reloadData];

}

 

UITableView 基本用法示例三:循环嵌套[2021-11-11更新]

-(void)initUI
{
[[[[sagit addTableView:nil]relate:TopBottom v:100 v2:200] backgroundColor:ColorRed] block:^(UITableView* table) {
table.addCell = ^(UITableViewCell *cell, NSIndexPath *indexPath) {
[cell backgroundColor:ColorGreen];
[[cell addLabel:nil text:cell.firstValue] toCenter];
[[[cell addSwitch:nil on:NO] onSwitch:^(UISwitch *view) {
if(view.on)
{
[self addTable:cell];
}
else
{
[cell.lastSubView removeFromSuperview];
[cell refleshTableHeight];
}

}] relate:Right v:50];

};
table.source=@[@{@"a":@"aa"},@{@"a":@"bb"},@{@"a":@"cc"}];
}];
}
-(void)addTable:(UITableViewCell*)cell
{
[[[[cell addTableView:nil] autoHeight:YES] backgroundColor:ColorBlack] block:^(UITableView* cellTable) {
[[cellTable onBottom:cell.lastSubView.preView] x:0];
cellTable.addCell = ^(UITableViewCell *childCell, NSIndexPath *indexPath) {
childCell.accessoryType=UITableViewCellAccessoryNone;
[[childCell backgroundColor:ColorRandom] width:1 height:100];
NSString * value=childCell.firstValue;
[[childCell addLabel:nil text:value] toCenter];
};
cellTable.afterReload = ^(UITableView *tableView) {
[cell refleshTableHeight];=@[@{@"b":@"aaaa"},@{@"b":@"bb"},@{@"b":@"cc"}];
}];
}

代码细节说明:

Table循环嵌套时,由于表格加载,有延后时,所以,需要在子表格的afterReolad事件(即加载完后)处理。

单元格新增了:refleshTableHeight:刷新表格高度。该方法仅会刷新单元格和表格的高度(不触发table的reload事件)。

循环效果图:

Sagit.Framework For IOS 自动布局教程:_Sagit.Framework_03

 

 

 

UICollectionView、UICollectionViewCell 基本定义

@interface UICollectionView(ST)
#pragma mark 核心扩展
typedef void(^AddCollectionCell)(UICollectionViewCell *cell,NSIndexPath *indexPath);
typedef BOOL(^DelCollectionCell)(UICollectionViewCell *cell,NSIndexPath *indexPath);
//!用于为Table追加每一行的Cell
@property (nonatomic,copy) AddCollectionCell addCell;
//!用于为Table移除行的Cell
@property (nonatomic,copy) DelCollectionCell delCell;
//!获取Table的数据源
@property (nonatomic,strong) NSMutableArray<id> *source;
//!设置Table的数据源
-(UITableView*)source:(NSMutableArray<id> *)dataSource;
@end

---------------------------------------------

@interface UICollectionViewCell(ST)
//!获取Cell的数据源
@property (nonatomic,strong) NSMutableDictionary<NSString*,id> *source;
//!设置Cell的数据源
-(UICollectionViewCell *)source:(NSMutableDictionary<NSString*,id> *)dataSource;
//!创建或复用Cell
+ (instancetype)reuseCell:(UICollectionView *)tableView index:(NSIndexPath *)index;
//!获取当前所在的table
-(UICollectionView*)table;

//!获取是否允许删除属性
//-(BOOL)allowDelete;
//!设置是否允许删除
//-(UITableView*)allowDelete:(BOOL)yesNo;
//!数据源中的第一个字段,系统自动设置
-(NSString*)firstValue;
-(UICollectionViewCell*)firstValue:(NSString*)value;
@end

 

这两个和上面两个的用法基本一致,功能比上面的还少,就不过多介绍了。

3、左滑菜单说明

如果左滑的菜单只有删除,那么只需要设置:

[table allowEdit:YES]

删除点击的事件:

table.delCell = ^BOOL(UITableViewCell *cell, NSIndexPath *indexPath)
{
[Sagit.RongYun removeFromBlacklist:cell.firstValue success:^{
[this.http get:UrlSetBlacklist paras:@{@"blackUserID":cell.firstValue, @"blackFlag":@"2"} success:^(STHttpModel *result) {
if (result.success)
{
[cell.table afterDelCell:indexPath];
}
} ];
} error:^(RCErrorCode status) {

}];

return false;
};

默认是处理完业务,return true;(之后框架会调用 afterDelCell 移除行并重绘高度)。

如果有异步操作,也可以先return false; 再根据结果自己调用 afterDelCell 方法。

如果涉及到添加多个菜单:

原生事件:

-(NSArray<UITableViewRowAction*>*)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath {
RCConversationModel *model = self.conversationListDataSource[indexPath.row];
UITableViewRowAction *del = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDestructive title:@"删除" handler:^(UITableViewRowAction * _Nonnull action,NSIndexPath *......
}];

UITableViewRowAction *top = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:@"置顶" handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) {
......
}];
top.backgroundColor = STColor(@"#fe9d00");
return @[del, top];
}

框架用法 [2020-09-17更新]

indexPath) {
[actions addAction:@"置顶" bgColor:ColorRed onAction:nil];
[actions addAction:@"删除2" bgColor:ColorBlack onAction:^(UITableViewCell *cell, NSIndexPath *indexPath) {
//点击事件。
}];
};

结果图:

Sagit.Framework For IOS 自动布局教程:_数据源_04

如果需要自定义滑动菜单:

【原生的方法:可以改变样式,但改变不了坐标,所以在原生的基础上添加自己的视图即可】

- (void)tableView:(UITableView *)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath
{

UITableViewCell *cell=[tableView cellForRowAtIndexPath:indexPath];
if(cell!=nil)
{
UIView *uiSwipeActionPullView=cell.superview.subviews[0]; //UISwipeActionPullView
if([uiSwipeActionPullView isKindOfClass:[UITableViewCell class]])
{
//IOS 13 以下。
for (UIView *view in tableView.subviews) {
if([view isKindOfClass:NSClassFromString(@"UISwipeActionPullView")])
{
uiSwipeActionPullView=view;
break;
}
}
}
//uiSwipeActionPullView=>UISwipeActionStandardButton => UIView,UIButtonLabel
for (UIView * btnView in uiSwipeActionPullView.subviews) {
[btnView backgroundColor:STDeviceColor];
[btnView removeAllSubViews];
[[[[[[btnView addButton:nil title:@"click" font:24 color:ColorGreen img:nil] width:120 height:0.8] layerCornerRadius:24]
toCenter:Y] backgroundColor:ColorBlue] x:20];
}
}
}

滑动后的布级层级:(IOS 13) 【IOS13以下的View层级是在UITableView下

Sagit.Framework For IOS 自动布局教程:_数据源_05

框架用法 [2020-09-17更新] 

indexPath) {
[actions addAction:^(UIView *cellSwipeView, NSIndexPath *indexPath) {
[[[[[[cellSwipeView addButton:nil title:@"click" font:24 color:ColorGreen img:nil] width:120 height:0.8] layerCornerRadius:24]
toCenter:Y] backgroundColor:ColorBlue] x:20];
} onAction:nil];
};

效果图:

 

Sagit.Framework For IOS 自动布局教程:_git_06

PS:addAction 有两个重载方法,一个用于原生的文字和背景色调整;另一个用于自定样式。

4、分区标题

原生用法:

// 设置表头的高度。如果使用自定义表头,该方法必须要实现,否则自定义表头无法执行,也不会报错
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 80*Ypt;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section

{

UIView *view=[[[UIView new] width:1 height:80] backgroundColor:[ColorBlue alpha:0.5]];
[[[view addLabel:nil text:@"title"] toCenter] sizeToFit];
[[view stSizeToFit] layerCornerRadius:20 byRoundingCorners:UIRectCornerTopLeft|UIRectCornerTopRight];

return view;
}

框架用法: [2021-11-11更新]

table.addSectionHeaderView = ^(UIView *sectionView, NSInteger section) {
[sectionView backgroundColor:[ColorBlue alpha:0.5]];
[[[sectionView addLabel:nil text:@"title"] toCenter] sizeToFit];
[[sectionView stSizeToFit] layerCornerRadius:20 byRoundingCorners:UIRectCornerTopLeft|UIRectCornerTopRight];
};

结果图片:

Sagit.Framework For IOS 自动布局教程:_Sagit.Framework_07

 

举报

相关推荐

0 条评论