IOS高访新浪微博界面(讲解如何自定义UITableViewCell,处理@#链接 特殊字符)

在开发过程中,有好多应用都会嵌入新浪微博的界面,今天整理一下代码。

首先看界面效果图:


   


Demo下载地址:http://download.csdn.net/detail/rhljiayou/6760745

思路:首先放一个UITableView,自定义一个UITableViewCell,分析新浪微博中的数据,并且显示在界面上,这个稍微费一下事,主要是分析数据并且算出位置。


还有要处理@#链接 特殊字符,并以不同颜色显示出,这个可以参考另外一遍博文:

http://blog.csdn.net/rhljiayou/article/details/17019651,讲的是正则表达式,不过里面有包含内容关于如何使@#链接 特殊字符处理的。可以通过AutoHyperlinks,稍加修改就可以写出完美的特殊字符处理。


今天我主要讲三点东西: 1、UITableViewCell的重用机制(不要范错误)2、自定义UITableViewCell  3、MVC 的思想

为什么要讲这些,这跟今天的 Demo 有关系吗?

答:关系重大,因为我发现有的同学用 UITableView 写东西的时候把所有的东西添加到系统的 UITableViewCell中去了,这样会导致一些问题,我觉得比较严重,所以就想写此文来让大家避免这些错误,看大家是否也范这样的错误了!


1、UITableViewCell的重用机制(不要范错误)

首先您先看这样的代码:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath  
  2. {  
  3.     static NSString *CellIdentifier = @"Cell";  
  4.     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];  
  5.     if (cell == nil) {  
  6.         cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];  
  7.         cell.selectionStyle = UITableViewCellSelectionStyleNone;  
  8.     }  
  9.       
  10.     UILabel *nameLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, 320, 20)];  
  11.     nameLabel.text = @"这是一个自定义的 name";  
  12.     [cell addSubview:nameLabel];  
  13.       
  14.     return cell;  
  15. }  


感觉有问题吗?(声明一下,我写代码都用 arc,所以大家看到代码没有release,是正常不是错误。)

肯定是有问题的,看这一句:[cell addSubview:nameLabel];大家先看一下我截的图:




有没有发现,我标注那几行,字体明显比其他的粗!那是因为我把tableView划动了几行,并且是把上面两行划过屏之外了,最后一行也划过屏幕之外了。如果你觉得的不够明显,自己可以写一写。


为什么会导致此问题呢,是 UITableViewCell 的重用机制,比如我屏幕上可以显示10行,那么就会创建10个 UITableViewCell,当我划动时,上面划出屏的UITableViewCell实际上是挂起状态,下面行出现到屏上实际是不会再创建 UITableViewCell 了,而是引用上面划出屏幕的 UITableViewCell,这样以来,每次划进屏后,那个cell上都会添加nameLabel,导致重叠重叠又重叠,所以会出现字体明显比别的粗些,因为有好几个label被重叠了。

避免此错误,只要给 nameLabel 再赋上值就好了,没必要再添加到cell上。


但是,有的同学为避免这个重叠错误,这样做了,请看以下代码:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath  
  2. {  
  3.     static NSString *CellIdentifier = @"Cell";  
  4.     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];  
  5.     if (cell == nil) {  
  6.         cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];  
  7.         cell.selectionStyle = UITableViewCellSelectionStyleNone;  
  8.     }else{  
  9.         UILabel *label = (UILabel*)[cell viewWithTag:200];  
  10.         [label removeFromSuperview];  
  11.     }  
  12.       
  13.     UILabel *nameLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, 320, 20)];  
  14.     nameLabel.text = @"这是一个自定义的 name";  
  15.     nameLabel.tag = 200;  
  16.     [cell addSubview:nameLabel];  
  17.       
  18.     return cell;  
  19. }  

把[label removeFromSuperview];这样解决,的确不会出现字体变粗的情况了,但是,新问题出现了。UITableViewCell 的重用机制体现何在?每个cell上都重新删除再添加,相当于每个cell都是独立的,这样就不能体现出UITableViewCell真正的优点了,它的优点就是重用机制,你只要添加一次再重新赋值就好了,为什么还要每次都重新添加,这样感觉即浪费资源又不能体现规范性还没有优点。


2、自定义UITableViewCell  

如果你的 cell 上很复杂,系统cell上的View根本不够用,那么就考虑自定义cell吧。

不推荐在- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath此方法中,

把所有需要的view 都添加到 cell 上。

推荐方法:

继承UITableViewCell创建自定义的CustomCell,代码如下:

CustomCell:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #import "CustomCell.h"  
  2.   
  3. @implementation CustomCell  
  4.   
  5. - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier  
  6. {  
  7.     self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];  
  8.     if (self) {  
  9.         // Initialization code  
  10.         _nameLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, 320, 20)];  
  11.         [self addSubview:_nameLabel];  
  12.     }  
  13.     return self;  
  14. }  
  15.   
  16. - (void)setSelected:(BOOL)selected animated:(BOOL)animated  
  17. {  
  18.     [super setSelected:selected animated:animated];  
  19.   
  20.     // Configure the view for the selected state  
  21. }  
  22.   
  23. @end  

使用:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath  
  2. {  
  3.     static NSString *CellIdentifier = @"CustomCell";  
  4.     CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];  
  5.     if (cell == nil) {  
  6.         cell = [[CustomCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];  
  7.         cell.selectionStyle = UITableViewCellSelectionStyleNone;  
  8.     }  
  9.       
  10.     cell.nameLabel.text = @"这是一个自定义的 name";  
  11.       
  12.     return cell;  
  13. }  


3、MVC 的思想

现在完整 app 都会从后台取数据,如果数据很复杂,你会如何让他们显示在界面上。

比如以下数据是从后台取出来的:

{
    "name": "rhl",
    "sex": "女",
    "job": "coder",
    "age": "0",
    "csdn": "http://blog.csdn.net/rhljiayou",
    "main": "3G/移动开发",
    "qq 群": "113820038"
}

这数据算少的算简单的,我只是用这个做一下例子,真实的数据有可能很多很复杂!

拿到数据后,都会把它解析成数组对象NSMutableDictionary *dict;

有二种写法

第一种:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath  
  2. {  
  3.     static NSString *CellIdentifier = @"CustomCell";  
  4.     CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];  
  5.     if (cell == nil) {  
  6.         cell = [[CustomCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];  
  7.         cell.selectionStyle = UITableViewCellSelectionStyleNone;  
  8.     }  
  9.       
  10.     cell.nameLabel.text = [dict objectForKey:@"name"];  
  11.     cell.sexLabel.text = [dict objectForKey:@"sex"];  
  12.     cell.jobLabel.text = [dict objectForKey:@"job"];  
  13.     cell.ageLabel.text = [dict objectForKey:@"age"];  
  14.     cell.csdnLabel.text = [dict objectForKey:@"csdn"];  
  15.     cell.mainLabel.text = [dict objectForKey:@"main"];  
  16.     cell.qqLabel.text = [dict objectForKey:@"qq群"];  
  17.       
  18.     return cell;  
  19. }  

这样也能达到预期效果,只是如果你此类中的代码非常之多,再添加这点代码其实也好,假如像我 demo 中的新浪微博中的数据,你就有可能头大了。

比如多个viewController中都用到此数据呢,你是不是也照样这样写一遍啊。由此看来,是不是感觉代码的藕合性有些高啊,就是说 view 和数据是在一块儿,有几套 view 就有几套数据这样写,那么我们为何不尝试把这些赋值的这些操作统一的就写一份儿呢?

接下来就是第二种写法:

在 CustomCell 中

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. -(void)setContent:(NSMutableDictionary*)dict  
  2. {  
  3.     self.nameLabel.text = [dict objectForKey:@"name"];  
  4.     self.sexLabel.text = [dict objectForKey:@"sex"];  
  5.     self.jobLabel.text = [dict objectForKey:@"job"];  
  6.     self.ageLabel.text = [dict objectForKey:@"age"];  
  7.     self.csdnLabel.text = [dict objectForKey:@"csdn"];  
  8.     self.mainLabel.text = [dict objectForKey:@"main"];  
  9.     self.qqLabel.text = [dict objectForKey:@"qq群"];  
  10. }  

用法

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath  
  2. {  
  3.     static NSString *CellIdentifier = @"CustomCell";  
  4.     CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];  
  5.     if (cell == nil) {  
  6.         cell = [[CustomCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];  
  7.         cell.selectionStyle = UITableViewCellSelectionStyleNone;  
  8.     }  
  9.     [cell setContent:dict];  
  10.     return cell;  
  11. }  

这样,我们只需要[cell setContent:dic];就能完成赋值操作!别的界面中也用到此 cell 时只需这一行代码就完成赋值了。

我一般拿到数据后会将其字典NSMutableDictionary封装成成模型对象,这样更符合 MVC 的思想。

所谓MVC,我这里搜到一个人的回答还是瞒详细的,

也很易懂:http://zhidao.baidu.com/link?url=giaoyhccUjcAiQjWVLB_nNI7-BsLPAq-gsDz_avnAGCvaPZW3hDmxLqNYsxG8dtSi5ciLCdUMyh1AVZsKCVDVq


ok,今天就先讲到这里,虽然此文是关于新浪微博的界面,但是其涉及到知识面想讲一下,因为看到好多同学都会犯同样的错误。

如有说的不对的地方,希望同学朋友们指出并讨论。


提外话:话说今天是平安夜,各种电影演唱会都在这一天推出,祝大家玩的愉快!


2013-12-31 10:08编辑



感谢这位朋友提出,Demo,有需要更新的地方的,我未考虑到一些问题如下:

新浪微博那里,有的微博有转发内容,有的没有,然后我定义的时候忽略了这一点,把所有的cell都添加上了转发的view。但是有的微博没有,这时候,cell再被重用的时候,原来转发的内容也被显示了。这时候我忽略了一点,就是没有清空转发的内容,然后就显示在界面上了,就出现了重叠。

新Demo下载地址:http://download.csdn.net/detail/rhljiayou/6791157



转载注明原著:http://blog.csdn.net/rhljiayou

版权声明:本文为博主原创文章,未经博主允许不得转载

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值