微信号:cocoachinabbs

介绍:CocoaChina苹果开发中文社区官方微信,提供教程资源、app推广营销、招聘、外包及培训信息、各类沙龙交流活动以及更多开发者服务.

iOS开发 | “我的”页面的纯代码做法

2018-01-11 09:00 无夜之星辰



app中常见的“我的”页面


大部分app都有“我的”页面,也就是个人中心,下图是我们公司app的“我的”页面:



这个页面的tableView我把它看做三部分:


表头:


表头


表尾:


表尾


主内容:


主内容


今天我们就来聊一聊主内容这一块的做法,为了不那么单调,我稍微改了一下,如下:



方案一:使用静态单元格


对于这种数据不变的tableView,使用静态单元格还是比较方便的,我认识的不少开发者也是采用的这种方法,不清楚的同学可以网上搜下,这里就不讨论了。


方案二:直接在cell上addSubview


首先我们封装好下面这种样式的cell:



@interface CQUserCenterCell : UITableViewCell


@property (nonatomic, strong) CQUserCenterCellModel *model;


/** 隐藏cell右边的箭头 */

- (void)hideIndicator;


@end


model:


@interface CQUserCenterCellModel : NSObject


@property (nonatomic, copy) NSString *icon;

@property (nonatomic, copy) NSString *title;


@end


那几个独立控件:积分label、未读信息label和夜间模式switch,作为controller的属性,直接添加在相应的cell上。代码如下:


/** 积分label */

@property (nonatomic, strong) UILabel *pointsLabel;

/** 未读消息 */

@property (nonatomic, strong) UILabel *unreadLabel;

/** 夜间模式开关 */

@property (nonatomic, strong) UISwitch *nightModeSwitch;


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    // 使用唯一复用id

    NSString *reuseCellID = [NSString stringWithFormat:@"%ld_%ld", indexPath.section, indexPath.row];

    CQUserCenterCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseCellID];

    if (!cell) {

        cell = [[CQUserCenterCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseCellID];

        cell.model = self.modelArray[indexPath.row];

        

        switch (indexPath.row) {

            case 2: // 我的积分

            {

                self.pointsLabel = [[UILabel alloc]initWithFrame:CGRectMake(140, 0, 100, 40)];

                [cell.contentView addSubview:self.pointsLabel];

                self.pointsLabel.textColor = [UIColor redColor];

                self.pointsLabel.font = [UIFont systemFontOfSize:14];

            }

                break;

                

            case 3: // 未读消息

            {

                self.unreadLabel = [[UILabel alloc] initWithFrame:CGRectMake(130, 5, 16, 16)];

                [cell.contentView addSubview:self.unreadLabel];

                self.unreadLabel.backgroundColor = [UIColor redColor];

                self.unreadLabel.textColor = [UIColor whiteColor];

                self.unreadLabel.font = [UIFont systemFontOfSize:12];

                self.unreadLabel.textAlignment = NSTextAlignmentCenter;

                self.unreadLabel.layer.cornerRadius = 8;

                self.unreadLabel.clipsToBounds = YES;

                self.unreadLabel.hidden = YES; // 默认隐藏

            }

                break;

                

            case 4: // 夜间模式

            {

                // 隐藏cell右边的箭头

                [cell hideIndicator];

                

                // 夜间模式开关

                self.nightModeSwitch = [[UISwitch alloc] init];

                [cell.contentView addSubview:self.nightModeSwitch];

                self.nightModeSwitch.center = CGPointMake(self.view.frame.size.width - 50, 20);

                [self.nightModeSwitch addTarget:self action:@selector(changeTheme:) forControlEvents:UIControlEventValueChanged];

            }

                break;

                

            default:

                break;

        }

        

    }

    return cell;

}


我这里使用的唯一cell复用id,避免了因cell复用带来的细节问题,也少写了一些代码。


这种方案的优点是:简单明了,任何段位的开发者来维护你的代码都无压力;缺点是代码都写在了C层,让C有点臃肿。


方案三:扩展


扩展cell:



@interface CQUserCenterCell (Util)


/** 设置积分 */

- (void)setPoints:(NSInteger)points;

/** 设置未读消息数量 */

- (void)setUnreadMessageNum:(NSInteger)unreadMessageNum;

/**

 添加控制夜间模式的switch


 @param handler 开启\关闭夜间模式时回调的block

 */

- (void)addNightModeSwitchWithHandler:(void(^)(BOOL isOn))handler;


@end


controller的代码相对简练了一些:


/** 积分cell */

@property (nonatomic, strong) CQUserCenterCell *pointsCell;

/** 未读消息cell */

@property (nonatomic, strong) CQUserCenterCell *unreadCell;

/** 夜间模式cell */

@property (nonatomic, strong) CQUserCenterCell *nightModeCell;


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    // 使用唯一复用id

    NSString *reuseCellID = [NSString stringWithFormat:@"%ld_%ld", indexPath.section, indexPath.row];

    CQUserCenterCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseCellID];

    if (!cell) {

        cell = [[CQUserCenterCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseCellID];

        cell.model = self.modelArray[indexPath.row];

        

        switch (indexPath.row) {

            case 2: // 我的积分

            {

                self.pointsCell = cell;

            }

                break;

                

            case 3: // 未读消息

            {

                self.unreadCell = cell;

            }

                break;

                

            case 4: // 夜间模式

            {

                [cell addNightModeSwitchWithHandler:^(BOOL isOn) {

                    [self changeTheme:isOn];

                }];

            }

                break;

                

            default:

                break;

        }

        

    }

    return cell;

}


// 加载数据


- (void)loadData {

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

        // 设置积分

        [self.pointsCell setPoints:200];

        // 设置未读消息数量

        [self.unreadCell setUnreadMessageNum:3];

    });

}


// 改变主题色

- (void)changeTheme:(BOOL)isNightMode {

    if (isNightMode) {

        self.tableView.backgroundColor = [UIColor grayColor];

    } else {

        self.tableView.backgroundColor = [UIColor whiteColor];

    }

}


我的做法


我用的方案二,因为最简单。

C层臃肿?不存在的,这种简单页面本来就写不到多少代码。


最后


想知道你们是怎么做的。


 
Cocoa开发者社区 更多文章 错过了淘宝、比特币,千万别错过小程序…… 一年一度的科技盛宴 CES2018热点前瞻 需要侧滑抽屉效果?一行代码足以! [译]Xcode 环境配置最佳实践 为了防止世界被破坏,春运的抢票攻略在等着你们
猜您喜欢 【有奖活动】猴年马月不再遥远,解放号帮你实现愿望! 我承认,我是被我的CTO害死的 【福利】行业报告免费赠,天生任性没办法! 程序猿的幽默,普通人看不懂... 红薯因 Swift 重写开源中国失败,貌似欲改用 Python