Sagit.Framework For IOS automatic layout tutorial: 15. Introduction to special usage of uitableview, uitableviewcell, uicollectionview, uicollectionviewcell [updated on September 17, 2020]

Time:2020-10-19

preface:

The framework encapsulates many functions for uitableview and uitableviewcell. Let’s start.

1. Basic definition of uitableview.

 

@interface UITableView(ST)

#Pragma mark core extension
typedef void(^OnAddTableCell)(UITableViewCell *cell,NSIndexPath *indexPath);
typedef BOOL(^OnDelTableCell)(UITableViewCell *cell,NSIndexPath *indexPath);
typedef void(^OnAddTableCellAction)(STUITableViewCellAction *cellAction, NSIndexPath *indexPath);
typedef void(^OnAddTableSectionView)(UIView *sectionView,NSInteger section);
typedef void(^OnAfterTableReloadData)(UITableView *tableView);
//! cell to append each row to a table
@property (nonatomic,copy) OnAddTableCell addCell;
//! cell to append each row to a table的滑动菜单
@property (nonatomic,copy) OnAddTableCellAction addCellAction;
//! used to append the title view of each group of sections to the table
@property (nonatomic,copy) OnAddTableSectionView addSectionView;
//! cell to remove rows for table
@property (nonatomic,copy) OnDelTableCell delCell;
//! used to trigger after loading data for table reloaddata
@property (nonatomic,copy) OnAfterTableReloadData afterReload;
//! get data source of table
@property (nonatomic,strong) NSMutableArray *source;
//! set data source of table
-(UITableView*)source:(NSMutableArray *)dataSource;
//! archive the height of all cells (controlled by the system) [archive format: Section key, [row array]]
@property (readonly,nonatomic,retain) NSMutableDictionary *heightForCells;

//! reuse cell (yes by default)
-(BOOL)reuseCell;
-(BOOL)reuseCell:(BOOL)yesNo;
//! automatically control the height of the table
-(BOOL)autoHeight;
//! set whether to automatically control the height of the table
-(UITableView*)autoHeight:(BOOL)yesNo;
//! get default uitableviewcellstyle
-(UITableViewCellStyle)cellStyle;
//! set default uitableviewcellstyle
-(UITableView*)cellStyle:(UITableViewCellStyle)style;
//! get whether delete attribute is allowed to be edited
-(BOOL)allowEdit;
//! set whether to allow editing [delete]
-(UITableView*)allowEdit:(BOOL)yesNo;
//! remove data sources and rows (and recalculate and refresh height)
-(UITableView*)afterDelCell:(NSIndexPath*)indexPath;
#Pragma mark extended properties
-(UITableView*)scrollEnabled:(BOOL)yesNo;
//! number of groups (default 1)
-(UITableView*)sectionCount:(NSInteger)count;
//! num number of each section: parameters can be passed: @ [@ "1", @ "2", @ "2", @ "1"] or: @ "1,2,2,1"
-(UITableView*)rowCountInSections:(id)nums;
@end

2. Basic definition of uitableviewcell:

@interface UITableViewCell(ST)
//! get the current table, (weak, cannot cause double strong reference)
@property (readonly,nonatomic,weak) UITableView *table;
//! get the data source of cell
@property (nonatomic,strong) id source;
//! cell whether the cell is reused. If so, do not add sub control to avoid repeated addition.
//@property (readonly,nonatomic,assign) BOOL isReused;
//! set data source of cell
-(UITableViewCell *)source:(id)dataSource;
//! create or reuse cells
+ (instancetype)reuseCell:(UITableView *)tableView index:(NSIndexPath *)index;
//! gets the number of rows where the cell is located
-(NSIndexPath*)indexPath;
-(UITableViewCell*)indexPath:(NSIndexPath*)indexPath;
//! gets whether the property is allowed to be deleted
-(BOOL)allowDelete;
//! set whether to allow deletion
-(UITableView*)allowDelete:(BOOL)yesNo;
//! the first field in the data source, which is automatically set by the system
-(NSString*)firstValue;
-(UITableViewCell*)firstValue:(NSString*)value;
//It is used when the height of the cell needs to be changed dynamically according to the height of the sub content after binding, and the height is refreshed again.
-(UITableViewCell*)resetHeightCache;
#Pragma mark extended properties
-(UITableViewCell*)accessoryType:(UITableViewCellAccessoryType)type;
-(UITableViewCell*)selectionStyle:(UITableViewCellSelectionStyle)style;

#Pragma mark extension
//! get the cell’s sliding menu item.
@property (nonatomic,strong) STUITableViewCellAction *action;

@end

Example 1 of basic usage of 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 represents that 100% < = 1 is processed as a percentage.
             cell.accessoryType=UITableViewCellAccessoryNone;
             cell.backgroundColor=ColorClear;
             
             
             //Data
             AnswerUserRankModel *model=[[AnswerUserRankModel new] initWithObject:cell.source];
             NSString *score=[[@( model.Score )Stringvalue] append: @ "Min"];
             
             [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]];
                   }];
              }];
             
         };
     }];

effect:

 

 

Example 2 of basic usage of uitableview:

[[[[sagit addTableView:@"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 is fixed.
            UIView *textView;
            
            If ([Title isequaltostring: @ "Introduction"])
            {
                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];
            }
        };
        
    }];

effect:

 

Data source settings:

-(void)initData
{
    [super initdata]; // load the data of sub UI.
    UITableView *table=STFirstTable;
    table.source= @[@ {@ "title": @ "name", @ "name": @ "nickname", @ "MaxLength": @ "15"},
                   @{@ "title": @ "Introduction", @ "name": @ "description", @ "holder": @ "please introduce yourself briefly! "},
                   @{@ "title": @ "company", @ "name": @ "company", @ "holder": @ "company! ",@"maxLength":@"20"},
                   @{@ "title": @ "age", @ "name": @ "age", @ "pick": @ "age"},
                   @{@ "title": @ "education", @ "name": @ "edu", @ "pick": @ "education"},
                   @{@ "title": @ "height", @ "name": @ "height", @ "pick": @ "height"},
                   @{@ "title": @ "constellation", @ "name": @ "constellation", @ "pick": @ "constellation"},
                   @{@ "title": @ "marriage", @ "name": @ "marrstatus", @ "pick": @ "marriage"},
                   @{@ "title": @ "profession", @ "name": @ "profession", @ "pick": @ "profession"},
                   @{@ "title": @ "income", @ "name": @ "waves", @ "pick": @ "monthly salary"}];
    
    [[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];
    
}

 

Basic definitions of uicollectionview and uicollectionviewcell

@interface UICollectionView(ST)
#Pragma mark core extension
typedef void(^AddCollectionCell)(UICollectionViewCell *cell,NSIndexPath *indexPath);
typedef BOOL(^DelCollectionCell)(UICollectionViewCell *cell,NSIndexPath *indexPath);
//! cell to append each row to a table
@property (nonatomic,copy) AddCollectionCell addCell;
//! cell to remove rows for table
@property (nonatomic,copy) DelCollectionCell delCell;
//! get data source of table
@property (nonatomic,strong) NSMutableArray *source;
//! set data source of table
-(UITableView*)source:(NSMutableArray *)dataSource;
@end

———————————————

@interface UICollectionViewCell(ST)
//! get the data source of cell
@property (nonatomic,strong) NSMutableDictionary *source;
//! set data source of cell
-(UICollectionViewCell *)source:(NSMutableDictionary *)dataSource;
//! create or reuse cells
+ (instancetype)reuseCell:(UICollectionView *)tableView index:(NSIndexPath *)index;
//! get the current table
-(UICollectionView*)table;

//! gets whether the property is allowed to be deleted
//-(BOOL)allowDelete;
//! set whether to allow deletion
//-(UITableView*)allowDelete:(BOOL)yesNo;
//! the first field in the data source, which is automatically set by the system
-(NSString*)firstValue;
-(UICollectionViewCell*)firstValue:(NSString*)value;
@end

 

The usage of these two and the above two are basically the same, and their functions are less than the above ones, but I just introduced them more.

3. Slide left menu description

If the left sliding menu only needs to be deleted, you only need to set:

[table allowEdit:YES]

Delete click events:

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;
    };

The default is to return true after processing the business; (after that, the framework will call afterdelcell to remove the row and redraw the height).

If there is an asynchronous operation, you can also return false first, and then call the afterdelcell method according to the result.

If adding multiple menus is involved:

Native event:

-(NSArray*)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath {
    RCConversationModel *model = self.conversationListDataSource[indexPath.row];
    UITableViewRowAction *del  = [UITableViewRowAction rowAction WithStyle:UITableViewRowActionStyleDestructive title : @ "delete" handler: ^ (uitableviewrowaction *_ Nonnull action,NSIndexPath * _ Nonnull indexPath) {
    ......
    }];
    
    UITableViewRowAction *top  = [UITableViewRowAction rowAction WithStyle:UITableViewRowActionStyleDefault title : @ "top" handler: ^ (uitableviewrowaction *_ Nonnull action, NSIndexPath * _ Nonnull indexPath) {
       ......
    }];
    top.backgroundColor        = STColor(@"#fe9d00");
    return @[del, top];
}

Framework usage [updated on September 17, 2020]

table.addCellAction = ^(STUITableViewCellAction *actions, NSIndexPath *indexPath) {
            [actions Addaction: @ "top" bgColor:ColorRed onAction :nil];
            [actions Addaction: @ "delete 2" bgColor:ColorBlack onAction :^(UITableViewCell *cell, NSIndexPath *indexPath) {
                //Click events.
            }];
        };

The results are as follows

If you need to customize the slide menu:

[native method: you can change the style, but you can’t change the coordinates, so you can add your own view based on the original method]

- (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]])
            {
                //Less than 13 IOS.
                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];
            }
        }
}

Fabric level after sliding: (IOS 13)【The view level below ios13 is under uitableview

Framework usage [updated on September 17, 2020]

 table.addCellAction = ^(STUITableViewCellAction *actions, NSIndexPath *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];
        };

design sketch:

 

PS: Addaction has two overloaded methods, one for native text and background color adjustment, and the other for custom styles.

4. Section title

Native usage:

//Set the height of the meter head. If the user-defined header is used, this method must be implemented, otherwise the custom header cannot be executed and no error will be reported
- (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;
}

Frame usage: [updated on September 17, 2020]

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

Results picture: