背景

在APP中列表是一种比较常见的数据展示方式,当有数据时,就显示数据;如果没有数据,一般不会显示一个空白页面,而是在空白页面上加一些提示信息,比如像下面这样:

不同的APP会有不同的设计,但不管是什么样的设计,它在整个APP内部应该是一致的,要变也只是文字或图片稍有不同。

现状

因为我们目前的项目还算比较庞大,所以这种列表无数据的情况出现了20多次,所以类似下面的代码出现了就有20多次。为什么说类似,因为是由不同的人写的,逻辑也是差不多,但真的各不相同,有的封装成一个方法,比如:setNoMessageView,有的直接写在viewDidLoad里面......

- (void)setNoMessageView{self.noInfoView = [[UIView alloc] initWithFrame:CGRectMake(0, 45, SCREEN_WIDTH, SCREEN_HEIGHT)];self.noInfoView.backgroundColor = [UIColor clearColor];[self.view addSubview:self.noInfoView];UIImageView *carImageView = [[UIImageView alloc] initWithFrame:CGRectMake((SCREEN_WIDTH-120)/2, 60, 120, 86)];[carImageView setImage:[UIImage imageNamed:@"no_message.png"]];[self.noInfoView addSubview:carImageView];UILabel *noInfoLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 160, SCREEN_WIDTH, 20)];noInfoLabel.textAlignment = NSTextAlignmentCenter;noInfoLabel.textColor = LCRGBColor(211, 211, 211);noInfoLabel.text = NSLocalizedString(@"Dear, no information", nil);noInfoLabel.backgroundColor = [UIColor clearColor];noInfoLabel.font = [LCFont systemFontOfSize:20];[self.noInfoView addSubview:noInfoLabel];}

先不考虑重复的问题,只是孤立的看上述代码,它也有一些问题:

  • self.noInfoView的frame应该视根据上下文获得的,而不是和屏幕大小绑定,而且yOffset是45也是不对的。
  • carImageView的frame是固定大小的,而图片有可能变。

第一个解决办法

因为创建noInfoView的代码基本差不多,我们可以封装出一个Util方法。

+ (UIView*)createNoMessageViewWithFrame:(CGRect)frame image:(UIImage*)image text:(NSString*)text
{UIView* noMessageView = [[UIView alloc] initWithFrame:frame];noMessageView.backgroundColor = [UIColor clearColor];UIImageView *carImageView = [[UIImageView alloc] initWithFrame:CGRectMake((frame.size.width-image.size.width)/2, 60, image.size.width, image.size.height)];[carImageView setImage:image];[noMessageView addSubview:carImageView];UILabel *noInfoLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 160, frame.size.width, 20)];noInfoLabel.textAlignment = NSTextAlignmentCenter;noInfoLabel.textColor = LCRGBColor(211, 211, 211);noInfoLabel.text = text;noInfoLabel.backgroundColor = [UIColor clearColor];noInfoLabel.font = [LCFont systemFontOfSize:20];[noMessageView addSubview:noInfoLabel];return noMessageView;
}

调用:

- (void)setNoMessageView
{CGRect rect = self.shopListView.frame;UIImage* image = [UIImage imageNamed:@"no_message.png"];NSString* text = NSLocalizedString(@"Dear, no information", nil);self.noInfoView = [HJUIUtil createNoMessageViewWithFrame:rect image:image text:text];[self.view addSubview:self.noInfoView];
}

这样改看起来好多了,把共性封装,把差异作为接口留出。然后其他地方原本要写20行代码,现在只要写5行,而且多个地方调用的代码不会有太大的出入,便于阅读和理解。

第二个解决办法

上面的办法已经不错了,不过除了写5行代码之外,还给ViewController增加了一个属性:noInfoView。现在仔细想一下noInfoView出现的原因,是因为TableView没有内容显示的时候,noInfoView才显示出来,否则就隐藏。可见,这个noInfoView和TableView是紧密联系的,我们可以从UITableView的状态得出noInfoView的状态。那为什么不把它绑定到UITableView上呢?好,那就给UITableView增加一个属性,叫做emptyView。

给一个系统的类增加属性不是那么的简单,但是只要看过SVPullToRefresh的代码,就知道怎么做了。
首先,给UITableView增加一个Category。

@interface UITableView(EmptyView)@property (nonatomic, strong, readonly) UIView *emptyView;-(void)addEmptyViewWithImageName:(NSString*)imageName title:(NSString*)title;@end

static char UITableViewEmptyView;@implementation UITableView(EmptyView)@dynamic emptyView;- (UIView *)emptyView
{return objc_getAssociatedObject(self, &UITableViewEmptyView);
}- (void)setEmptyView:(UIView *)emptyView
{[self willChangeValueForKey:@"HJEmptyView"];objc_setAssociatedObject(self, &UITableViewEmptyView,emptyView,OBJC_ASSOCIATION_ASSIGN);[self didChangeValueForKey:@"HJEmptyView"];
}-(void)addEmptyViewWithImageName:(NSString*)imageName title:(NSString*)title
{if (!self.emptyView){CGRect frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);UIImage* image = [UIImage imageNamed:imageName];NSString* text = title;UIView* noMessageView = [[UIView alloc] initWithFrame:frame];noMessageView.backgroundColor = [UIColor clearColor];UIImageView *carImageView = [[UIImageView alloc] initWithFrame:CGRectMake((frame.size.width-image.size.width)/2, 60, image.size.width, image.size.height)];[carImageView setImage:image];[noMessageView addSubview:carImageView];UILabel *noInfoLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 160, frame.size.width, 20)];noInfoLabel.textAlignment = NSTextAlignmentCenter;noInfoLabel.textColor = LCRGBColor(211, 211, 211);noInfoLabel.text = text;noInfoLabel.backgroundColor = [UIColor clearColor];noInfoLabel.font = [LCFont systemFontOfSize:20];[noMessageView addSubview:noInfoLabel];[self addSubview:noMessageView];self.emptyView = noMessageView;}}@end

然后外部调用就很简单了,没有额外的属性,而且一句话就搞定。

[self.shopListView.shopListTableView addEmptyViewWithImageName:@"no_message.png" title:@"Dear, no information"];

然后在加载数据前进行判定是否显示emptyView

self.shopListView.shopListTableView.emptyView.hidden = ([self.dataArray count] != 0);

转载于:https://www.cnblogs.com/yulang314/p/5084372.html

代码优化之减少重复代码-实践相关推荐

  1. Androud 如何有效减少重复代码

    前言 重复的代码一直都是可维护性的大敌,重构的重要任务之一也就是要去除掉重复的代码,有效的减少重复代码,可以大大提高软件的扩展性. 在Android开发中,很容易产生重复的代码.因为Android是组 ...

  2. Python高能小技巧:用海象操作符减少重复代码

    导读:赋值表达式(assignment expression)是Python 3.8新引入的语法,它会用到海象操作符(walrus operator).这种写法可以解决某些持续已久的代码重复问题.a ...

  3. 运用aop做日志,实现请求方法的入参、返回结果日志统一打印,避免日志打印格式杂乱,同时减少重复代码

    文章目录 一.自定义注解 二.切面类 三.应用 一.自定义注解 自定义切面注解@PrintlnLog 用来输出日志,注解权限 @Target({ElementType.METHOD}) 限制只在方法上 ...

  4. 继承第一课:减少重复代码

    #include<iostream> using namespace std; #include<string> class basepage{     public:    ...

  5. Effective前端5:减少前端代码耦合

    什么是代码耦合?代码耦合的表现是改了一点毛发而牵动了全身,或者是想要改点东西,需要在一堆代码里面找半天.由于前端需要组织js/css/html,耦合的问题可能会更加明显,下面按照耦合的情况分别说明: ...

  6. java重复代码重构_重构重复代码

    java重复代码重构 As a software engineer working on a large project, you'll likely be asked to do cleanup w ...

  7. 从阿里跳槽来的工程师,分享了三套干掉 “重复代码”方式,真的太绝了!

     附:糖豆广场舞永久会员TV版 软件工程师和码农最大的区别就是平时写代码时习惯问题,码农很喜欢写重复代码而软件工程师会利用各种技巧去干掉重复的冗余代码. 业务同学抱怨业务开发没有技术含量,用不到设计模 ...

  8. Shell脚本,循环语句用于减少程序代码冗余和重复,for语句,while语句,使用let进行变量自增

    Shell脚本,循环语句用于减少程序代码冗余和重复,for语句,while语句 一.for语法: 1. for 变量 in 值列表 do 命令序列 done 例子:输出循环中的所有值 for i in ...

  9. usercf代码java_基于用户的协同过滤算法(UserCF)原理以及代码实践

    简介 协同过滤(collaborative filtering)是一种在推荐系统中广泛使用的技术.该技术通过分析用户或者事物之间的相似性,来预测用户可能感兴趣的内容并将此内容推荐给用户.这里的相似性可 ...

最新文章

  1. Debug Assert Failed 怎么办?
  2. php 数组值sum,php sum数组值(如果特定列的值重复)
  3. 云熙板式家具参数化拆单软件免锁版_数控开料机拆单软件如何选择?
  4. POJ 3669 简单BFS
  5. 图形学基础--深入浅出的微积分书籍 《普林斯顿微积分读本》和《托马斯微积分》
  6. Scratch编程与游戏:和电脑玩大富翁游戏
  7. IIS的ISAPI接口
  8. 【项目实训】微信公众号获取用户openid
  9. mysql让局域网访问权限_mysql 设置局域网内可访问
  10. 如何批量导出QQ空间相册到电脑中
  11. opencv视频拼接 opencv视频拼接优化
  12. 单机传奇找不到登陆器服务器列表,如果传奇服务端里面没有带登陆器怎么办?...
  13. RDS报警问题解决过程
  14. Linux优秀软件整理 - 摘自Linux 开源中国
  15. bash: /home/jdk/jdk1.8.0_261/bin/java: /lib/ld-linux.so.2: bad ELF interpre问题
  16. PS磨皮插件portraiture最新版磨皮工具
  17. java jcifs ntlm_Java 使用NTLM身份验证使用soap服务
  18. unik的命令行-解释说明
  19. Set集合之TreeSet
  20. 微信小程序申请开通直播功能

热门文章

  1. 还在对java类、类的加载一知半解?这篇文章相信会解决你80%的困惑
  2. VUE—从入门到飞起(二)
  3. 七、排序(3)——线性排序
  4. 2、ShardingSphere 之 Sharding-JDBC实现水平分表
  5. 公告牌为什么有些是纸质,有些是电子的
  6. Linux——线程(总结)
  7. 计算机二级vfp模拟考试题,计算机等级考试二级VFP模拟练习题[10]
  8. get方式乱码及MAC异常
  9. Import和Assembly
  10. tpp letter