温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

UIKit框架(21)UITableView实现复杂单元格(二)

发布时间:2020-04-10 16:22:33 来源:网络 阅读:511 作者:ymanmeng123 栏目:移动开发

继续介绍第二种实现复杂单元格的方式 ---- 使用storyboard中的prototype cell


  • prototype Cell介绍

在storyboard或xib中使用tableView时,可以添加prototype cells,其好处是:

1)可以直接进行自定义cell的设置

2)通过设置cell的重用ID,在调用出队列方法时如果没有可重用的则创建一个新的

     UIKit框架(21)UITableView实现复杂单元格(二)

注:一个tableView中可以设计多个prototype cell,重用ID不同即可

使用prototype cell 设计tableView是最常用的一种方式!


使用prototype cell相比较于纯代码,可以简化两处编程


  • 简化cell获取的代码

使用了prototype cell之后,从tableView的重用队列获取指定ID的cell,如果获取不出来,会自动创建一个相同ID的prototype cell的副本,不再需要alloc+init进行创建

//1.1 实现类方法,获取cell
+ (AMHeroCell *)cellWithTableView:(UITableView *)tableView
{
    AMHeroCell * cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
    return cell;
}


  • 简化cell的子视图设定

使用storyboard设计cell内部的子视图,也就是说不需要在代码中创建子视图并进行自动布局,这些工作全部可以在storyboard中快速完成。

也就是说,上篇文章中,介绍的1.2 1.3这两步不再需要



  • 案例:模拟实现大众点评的首页

prototype cell是我们实现复杂tableView的一种快速开发手段

如实现如下截图的效果:

    UIKit框架(21)UITableView实现复杂单元格(二)

可以看到:

    三个section,每个section中的cell样式不同及个数不同

    第一个section:一个cell,scrollView,内部有很多按钮

    第二个section:两个cell,活动信息cell

    第三个section:很多个cell,产品信息cell


1)在storyboard设计出这三种cell

    UIKit框架(21)UITableView实现复杂单元格(二)

    每种cell设定不同的ID

3)创建每个cell需要显示的数据模型类

4)每种cell分别关联UITableViewCell的子类

    子类内部分别实现三步操作(见UIKit框架(21)UITableView实现复杂单元格(一))

5)控制器管理所有的数据模型并实现数据源、代理方法

#pragma mark - tableView 
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 3;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if (section == 0 ) {
        return 1;
    }
    else if ( section == 1 ) {
        return self.activityArray.count;
    }
    else if ( section == 2 ) {
        return self.goodsArray.count;
    }
    else {
        return 0;
    }
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if ( indexPath.section == 0 ) {
        return [AMFunctionSelectionCell cellWithTableView:tableView];
    }
    else if ( indexPath.section == 1 ) {
        return [AMActivityCell cellWithTableView:tableView];
    }
    else if ( indexPath.section == 2 ) {
        return [AMGoodsInfoCell cellWithTableView:tableView];
    }
    else {
        return nil;
    }
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if ( indexPath.section == 0 ) {
        return [AMFunctionSelectionCell cellHeight];
    }
    else if ( indexPath.section == 1 ) {
        return [AMActivityCell cellHeight];
    }
    else if ( indexPath.section == 2 ) {
        return [AMGoodsInfoCell cellHeight];
    }
    else {
        return 0;
    }
}
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if ( indexPath.section == 0 ) {
        
    }
    else if ( indexPath.section == 1) {
        ((AMActivityCell*)cell).activityModel = self.activityArray[indexPath.row];
    }
    else if ( indexPath.section == 2 ) {
        ((AMGoodsInfoCell*)cell).goodsInfoModel = self.goodsArray[indexPath.row];
    }
}


  • 案例扩展:加载更多

在最后一个section下面增加一个加载更多按钮

    UIKit框架(21)UITableView实现复杂单元格(二)

点击后,可以模拟一个简单的增加cell的操作

1)使用xib设计一个这个底部视图

2)关联一个UIView的子类并提供类方法快速创建

+ (AMGoodsInfoFooterView *)view
{
    return [[[NSBundle mainBundle] loadNibNamed:@"AMGoodinfoFooterView" owner:nil options:nil]lastObject];
}

3)控制器实现tableView的数据源方法

- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
    if ( section == 2 ) {
        AMGoodsInfoFooterView * v =  [AMGoodsInfoFooterView view];
        v.delegate = self;
        return v;
    }
    else {
        return nil;
    }
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
    if ( section == 2 ) {
        return 40;
    }
    else {
        return 5;
    }
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    return 5;
}

    说明:两处返回5的目的是让三个section之间的空隙不要太大

4)加载更多按钮被点击时,将点击产生这个时间通过代理传递给控制器

//UIView子类提出代理协议并添加代理属性
@protocol AMGoodsInfoFooterViewDelegate <NSObject>
@optional
- (void) footerViewLoadMoreGoods;
@end
@interface AMGoodsInfoFooterView : UIView
+ (AMGoodsInfoFooterView *) view;
@property (nonatomic, weak) id<AMGoodsInfoFooterViewDelegate> delegate;
@end

5)控制器成为代理并实现代理方法

成为代理的操作在3)中已有

代理方法的实现:(简单模拟)

- (void)footerViewLoadMoreGoods
{
    AMGoodsInfoModel * model = [[AMGoodsInfoModel alloc] init];
    model.icon = self.goodsArray[0].icon;
    model.goodTitle = @"东软食堂";
    model.goodFooter = @"已售999999999";
    model.goodDesc = @"吃了你就知道了";
    model.priceValue = @"8";
    [self.goodsArray addObject:model];
    
    NSIndexSet * s = [NSIndexSet indexSetWithIndex:2];
    [self.tableView reloadSections:s withRowAnimation:UITableViewRowAnimationLeft];
}





向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI