UI基础--UITableView实现仿微博页面
需求:类似于微博内容页面的展示,内容包括有头像、呢称、会员标志、微博内容、微博图片(可有可没有)。具体效果图:
分析:
1、看界面,明显可以使用UITableView来实现显示微博数据;
2、但是,UITableView系统自定的cell无法满足需要,因为内容包括有头像、呢称、会员标志、微博内容、微博图片等等,所以这时就需要考虑自定义cell了;
3、在自定义cell时,可以考虑把各控件的frame抽出来封装成一个类,计算frame以及行高;
实例的文件结构:
实现的具体步骤:
1、自定义数据模型类,并测试数据是否能正常加载;
2、设置storyBoard,把UIViewController改为UITableViewController,,并更改controller文件为继承自UITableViewController的自定义文件,设置关联;
3、自定义cell,由于每行数据的高度都是不规则的,所以考虑先自定义好frame再来写自定义cell。属性包括frame模型以及生成可重用cell的方法,要注意的是需要重写initWithStytle方法,写给cell各子控件赋值以及生成frame的方法;
4、自定义frame,属性包括模型数据和行高以及cell中各个子控件的frame;
5、在控制器中写UITableView的 数据显示的方法;
具体的代码:
Category:
1 // 2 // NSString+Ext.m 3 // 12-24-MicroBlog 4 // 5 // Created by xiaomoge on 14/12/24. 6 // Copyright (c) 2014年 xiaomoge. All rights reserved. 7 // 8 9 #import "NSString+Ext.h" 10 11 @implementation NSString (Ext) 12 //取得字体的大小 13 - (CGSize)setTextSize:(CGSize)maxSize andFontSize:(CGFloat)fontSize { 14 return [self boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:fontSize]} context:nil].size; 15 } 16 @end
Model:
1 // 2 // JWMicroBlog.h 3 // 12-24-MicroBlog 4 // 5 // Created by xiaomoge on 14/12/24. 6 // Copyright (c) 2014年 xiaomoge. All rights reserved. 7 // 8 9 #import <Foundation/Foundation.h> 10 11 @interface JWMicroBlog : NSObject 12 @property (nonatomic,copy) NSString *text; 13 @property (nonatomic,copy) NSString *icon; 14 @property (nonatomic,copy) NSString *name; 15 @property (nonatomic,copy) NSString *picture; 16 @property (nonatomic,assign,getter=isVip) BOOL vip; 17 - (instancetype)initWithDic:(NSDictionary *)dic; 18 + (instancetype)microBlogWithDic:(NSDictionary *)dic; 19 + (NSArray *)microBlogList; 20 @end
1 // 2 // JWMicroBlog.m 3 // 12-24-MicroBlog 4 // 5 // Created by xiaomoge on 14/12/24. 6 // Copyright (c) 2014年 xiaomoge. All rights reserved. 7 // 8 9 #import "JWMicroBlog.h" 10 11 @implementation JWMicroBlog 12 - (instancetype)initWithDic:(NSDictionary *)dic { 13 if (self = [super init]) { 14 [self setValuesForKeysWithDictionary:dic]; 15 } 16 return self; 17 } 18 + (instancetype)microBlogWithDic:(NSDictionary *)dic { 19 return [[self alloc] initWithDic:dic]; 20 } 21 + (NSArray *)microBlogList { 22 NSArray *datas = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"microblog" ofType:@"plist"]]; 23 NSMutableArray *temp = [NSMutableArray array]; 24 25 for (NSDictionary *dic in datas) { 26 JWMicroBlog *blog = [JWMicroBlog microBlogWithDic:dic]; 27 [temp addObject:blog]; 28 } 29 return temp; 30 } 31 @end
1 // 2 // JWMicroBlogFrame.h 3 // 12-24-MicroBlog 4 // 5 // Created by xiaomoge on 14/12/24. 6 // Copyright (c) 2014年 xiaomoge. All rights reserved. 7 // 8 #define NAMEFONT 13 9 #define TEXTFONT 14 10 #import <UIKit/UIKit.h> 11 #import "JWMicroBlog.h" 12 @interface JWMicroBlogFrame : NSObject 13 /* 14 数据模型 15 */ 16 @property (nonatomic,strong) JWMicroBlog *microBlog; 17 /* 18 头像frame 19 */ 20 @property (nonatomic,assign,readonly) CGRect iconFrame; 21 /* 22 昵称frame 23 */ 24 @property (nonatomic,assign,readonly) CGRect nameFrame; 25 /* 26 vipframe 27 */ 28 @property (nonatomic,assign,readonly) CGRect vipFrame; 29 /* 30 内容frame 31 */ 32 @property (nonatomic,assign,readonly) CGRect textFrame; 33 /* 34 图片frame 35 */ 36 @property (nonatomic,assign,readonly) CGRect pictureFrame; 37 /* 38 行高 39 */ 40 @property (nonatomic,assign,readonly) CGFloat rowHeight; 41 /* 42 获取数据的方法 43 */ 44 + (NSArray *)microBlogFrameList; 45 @end
1 // 2 // JWMicroBlogFrame.m 3 // 12-24-MicroBlog 4 // 5 // Created by xiaomoge on 14/12/24. 6 // Copyright (c) 2014年 xiaomoge. All rights reserved. 7 // 8 9 #import "JWMicroBlogFrame.h" 10 #import "NSString+Ext.h" 11 @implementation JWMicroBlogFrame 12 /* 13 重写set方法 14 */ 15 - (void)setMicroBlog:(JWMicroBlog *)microBlog { 16 17 _microBlog = microBlog; 18 //间距 19 CGFloat margin = 10; 20 //头像 21 CGFloat iconW = 40; 22 CGFloat iconH = 40; 23 CGFloat iconX = margin; 24 CGFloat iconY = margin; 25 _iconFrame = CGRectMake(iconX, iconY, iconW, iconH); 26 27 //昵称 28 CGSize nameSize = [microBlog.name setTextSize:CGSizeMake(MAXFLOAT, MAXFLOAT) andFontSize:NAMEFONT];//取得昵称文字的大小,调用了分类的一个方法 29 CGFloat nameX = CGRectGetMaxX(_iconFrame) + margin;//X值是头像的最大X值加上间距 30 CGFloat nameY = (iconH + margin) * 0.5;//Y值是头像的高度加上间距的一半,这里用 * 比用 / 好,速度更快 31 _nameFrame = CGRectMake(nameX, nameY, nameSize.width, nameSize.height); 32 33 //vip 34 CGFloat vipW = 14; 35 CGFloat vipH = 14; 36 CGFloat vipX = CGRectGetMaxX(_nameFrame);//X值是昵称的最大X值 37 CGFloat vipY = nameY; 38 if (microBlog.isVip) {//如果模型数据中有vip的数据,才需要定义vip图片的frame 39 _vipFrame = CGRectMake(vipX, vipY, vipW, vipH); 40 } 41 42 //内容 43 CGSize textSize = [microBlog.text setTextSize:CGSizeMake(355, MAXFLOAT) andFontSize:TEXTFONT]; 44 CGFloat textX = margin; 45 CGFloat textY = CGRectGetMaxY(_iconFrame) + margin;//Y值是头像的最大Y值加上间距 46 _textFrame = CGRectMake(textX, textY, textSize.width, textSize.height); 47 48 //图片 49 CGFloat pictureW = 100; 50 CGFloat pictureH = 100; 51 CGFloat pictureX = margin; 52 CGFloat pictureY = CGRectGetMaxY(_textFrame) + margin;//Y值是内容的最大Y值加上间距 53 if (microBlog.picture) {//如果模型数据中有微博图片的数据,才需要定义frame 54 _pictureFrame = CGRectMake(pictureX, pictureY, pictureW, pictureH); 55 } 56 57 //行高 58 CGFloat textMax = CGRectGetMaxY(_textFrame);//定义一个内容的最大Y值 59 CGFloat pictureMax = CGRectGetMaxY(_pictureFrame);//定义一个微博图片的最大Y值 60 _rowHeight = MAX(textMax, pictureMax) + margin;//行高是根据是否有微博图片来决定的。这里的MAX函数其实就是返回一个最大值 61 } 62 + (NSArray *)microBlogFrameList { 63 NSArray *microBlog = [JWMicroBlog microBlogList]; 64 65 NSMutableArray *tem = [NSMutableArray array]; 66 67 for (JWMicroBlog *blog in microBlog) { 68 JWMicroBlogFrame *frame = [[JWMicroBlogFrame alloc] init]; 69 frame.microBlog = blog; 70 [tem addObject:frame]; 71 } 72 return tem; 73 } 74 @end
View:
1 // 2 // JWMicroBlogCell.h 3 // 12-24-MicroBlog 4 // 5 // Created by xiaomoge on 14/12/24. 6 // Copyright (c) 2014年 xiaomoge. All rights reserved. 7 // 8 9 #import <UIKit/UIKit.h> 10 @class JWMicroBlogFrame; 11 @interface JWMicroBlogCell : UITableViewCell 12 @property (nonatomic,strong) JWMicroBlogFrame *microBlogFrame; 13 + (JWMicroBlogCell *)cellWithTableView:(UITableView *)tableView; 14 @end
1 // 2 // JWMicroBlogCell.m 3 // 12-24-MicroBlog 4 // 5 // Created by xiaomoge on 14/12/24. 6 // Copyright (c) 2014年 xiaomoge. All rights reserved. 7 // 8 9 #import "JWMicroBlogCell.h" 10 #import "JWMicroBlogFrame.h" 11 @interface JWMicroBlogCell () 12 @property (nonatomic,weak) UIImageView *iconView;//头像view 13 @property (nonatomic,weak) UILabel *nameLabel;//昵称view 14 @property (nonatomic,weak) UIImageView *vipView;//vip图片view 15 @property (nonatomic,weak) UILabel *textView;//内容view 16 @property (nonatomic,weak) UIImageView *pictureView;//微博图片view 17 @end 18 @implementation JWMicroBlogCell 19 /* 20 快速构造一个可重用的cell 21 */ 22 + (JWMicroBlogCell *)cellWithTableView:(UITableView *)tableView { 23 static NSString *resue = @"bolg";//缓存池标识 24 JWMicroBlogCell *cell = [tableView dequeueReusableCellWithIdentifier:resue]; 25 if (!cell) { 26 cell = [[self alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:resue]; 27 } 28 return cell; 29 } 30 /* 31 重写init方法,添加各控件 32 */ 33 - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { 34 if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) { 35 //头像子控件 36 UIImageView *icon = [[UIImageView alloc] init]; 37 [self.contentView addSubview:icon]; 38 self.iconView = icon; 39 40 //昵称子控件 41 UILabel *name = [[UILabel alloc] init]; 42 [self.contentView addSubview:name]; 43 self.nameLabel = name; 44 name.font = [UIFont systemFontOfSize:NAMEFONT]; 45 46 //vip子控件 47 UIImageView *vip = [[UIImageView alloc] init]; 48 [self.contentView addSubview:vip]; 49 self.vipView = vip; 50 51 //内容子控件 52 UILabel *text = [[UILabel alloc] init]; 53 [self.contentView addSubview:text]; 54 self.textView = text; 55 text.numberOfLines = 0; 56 text.font = [UIFont systemFontOfSize:TEXTFONT]; 57 58 //图片子控件 59 UIImageView *picture = [[UIImageView alloc] init]; 60 [self.contentView addSubview:picture]; 61 self.pictureView = picture; 62 } 63 return self; 64 } 65 /* 66 重写set方法,设置cell中各控件的内容和frame 67 */ 68 - (void)setMicroBlogFrame:(JWMicroBlogFrame *)microBlogFrame { 69 _microBlogFrame = microBlogFrame; 70 [self setSubviewsContent];//设置cell中各控件显示的内容 71 [self setSubviewsFrame];//设置cell中各控件的frame 72 } 73 /* 74 设置cell中各控件显示的内容 75 */ 76 - (void)setSubviewsContent { 77 JWMicroBlog *msg = self.microBlogFrame.microBlog; 78 self.iconView.image = [UIImage imageNamed:msg.icon]; 79 self.nameLabel.text = msg.name; 80 if (msg.isVip) {//如果是vip,则昵称颜色设置为红色,否则为黑色 81 self.vipView.image = [UIImage imageNamed:@"vip"]; 82 self.nameLabel.textColor = [UIColor redColor]; 83 }else { 84 self.nameLabel.textColor = [UIColor blackColor]; 85 } 86 self.textView.text = msg.text; 87 self.pictureView.image = [UIImage imageNamed:msg.picture]; 88 } 89 /* 90 设置cell中各控件的frame 91 */ 92 - (void)setSubviewsFrame { 93 self.iconView.frame = self.microBlogFrame.iconFrame; 94 self.nameLabel.frame = self.microBlogFrame.nameFrame; 95 self.vipView.frame = self.microBlogFrame.vipFrame; 96 self.textView.frame = self.microBlogFrame.textFrame; 97 self.pictureView.frame = self.microBlogFrame.pictureFrame; 98 } 99 @end
Controller:
1 // 2 // JWController.m 3 // 12-24-MicroBlog 4 // 5 // Created by xiaomoge on 14/12/24. 6 // Copyright (c) 2014年 xiaomoge. All rights reserved. 7 // 8 9 #import "JWController.h" 10 #import "JWMicroBlog.h" 11 #import "JWMicroBlogCell.h" 12 #import "JWMicroBlogFrame.h" 13 @interface JWController ()<UITableViewDataSource> 14 //frame模型数组 15 @property (nonatomic,strong) NSArray *microBlogFrame; 16 @end 17 @implementation JWController 18 #pragma mark - 懒加载 19 - (NSArray *)microBlogFrame { 20 if (!_microBlogFrame) {//如果为空 21 _microBlogFrame = [JWMicroBlogFrame microBlogFrameList]; 22 } 23 return _microBlogFrame; 24 } 25 #pragma mark - 隐藏状态栏 26 - (BOOL)prefersStatusBarHidden { 27 return YES; 28 } 29 - (void)viewDidLoad { 30 [super viewDidLoad]; 31 } 32 #pragma mark - UITableViewDataSource方法 33 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 34 return self.microBlogFrame.count;//返回每组行的多少 35 } 36 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 37 JWMicroBlogCell *cell = [JWMicroBlogCell cellWithTableView:tableView]; 38 cell.microBlogFrame = self.microBlogFrame[indexPath.row];//取得对应行的数据 39 return cell; 40 } 41 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { 42 return [self.microBlogFrame[indexPath.row] rowHeight];//返回每行数据的行高 43 } 44 @end