您的位置:首页 > 产品设计 > UI/UE

UI基础--UITableView实现仿微博页面

2015-01-04 00:20 489 查看
需求:类似于微博内容页面的展示,内容包括有头像、呢称、会员标志、微博内容、微博图片(可有可没有)。具体效果图:



分析:
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:

//
//  NSString+Ext.m
//  12-24-MicroBlog
//
//  Created by xiaomoge on 14/12/24.
//  Copyright (c) 2014年 xiaomoge. All rights reserved.
//

#import "NSString+Ext.h"

@implementation NSString (Ext)
//取得字体的大小
- (CGSize)setTextSize:(CGSize)maxSize andFontSize:(CGFloat)fontSize {
return [self boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:fontSize]} context:nil].size;
}
@end


Model:

//
//  JWMicroBlog.h
//  12-24-MicroBlog
//
//  Created by xiaomoge on 14/12/24.
//  Copyright (c) 2014年 xiaomoge. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface JWMicroBlog : NSObject
@property (nonatomic,copy) NSString *text;
@property (nonatomic,copy) NSString *icon;
@property (nonatomic,copy) NSString *name;
@property (nonatomic,copy) NSString *picture;
@property (nonatomic,assign,getter=isVip) BOOL vip;
- (instancetype)initWithDic:(NSDictionary *)dic;
+ (instancetype)microBlogWithDic:(NSDictionary *)dic;
+ (NSArray *)microBlogList;
@end


//
//  JWMicroBlog.m
//  12-24-MicroBlog
//
//  Created by xiaomoge on 14/12/24.
//  Copyright (c) 2014年 xiaomoge. All rights reserved.
//

#import "JWMicroBlog.h"

@implementation JWMicroBlog
- (instancetype)initWithDic:(NSDictionary *)dic {
if (self = [super init]) {
[self setValuesForKeysWithDictionary:dic];
}
return self;
}
+ (instancetype)microBlogWithDic:(NSDictionary *)dic {
return [[self alloc] initWithDic:dic];
}
+ (NSArray *)microBlogList {
NSArray *datas = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"microblog" ofType:@"plist"]];
NSMutableArray *temp = [NSMutableArray array];

for (NSDictionary *dic in datas) {
JWMicroBlog *blog = [JWMicroBlog microBlogWithDic:dic];
[temp addObject:blog];
}
return temp;
}
@end


//
//  JWMicroBlogFrame.h
//  12-24-MicroBlog
//
//  Created by xiaomoge on 14/12/24.
//  Copyright (c) 2014年 xiaomoge. All rights reserved.
//
#define NAMEFONT 13
#define TEXTFONT 14
#import <UIKit/UIKit.h>
#import "JWMicroBlog.h"
@interface JWMicroBlogFrame : NSObject
/*
数据模型
*/
@property (nonatomic,strong) JWMicroBlog *microBlog;
/*
头像frame
*/
@property (nonatomic,assign,readonly) CGRect iconFrame;
/*
昵称frame
*/
@property (nonatomic,assign,readonly) CGRect nameFrame;
/*
vipframe
*/
@property (nonatomic,assign,readonly) CGRect vipFrame;
/*
内容frame
*/
@property (nonatomic,assign,readonly) CGRect textFrame;
/*
图片frame
*/
@property (nonatomic,assign,readonly) CGRect pictureFrame;
/*
行高
*/
@property (nonatomic,assign,readonly) CGFloat rowHeight;
/*
获取数据的方法
*/
+ (NSArray *)microBlogFrameList;
@end


//
//  JWMicroBlogFrame.m
//  12-24-MicroBlog
//
//  Created by xiaomoge on 14/12/24.
//  Copyright (c) 2014年 xiaomoge. All rights reserved.
//

#import "JWMicroBlogFrame.h"
#import "NSString+Ext.h"
@implementation JWMicroBlogFrame
/*
重写set方法
*/
- (void)setMicroBlog:(JWMicroBlog *)microBlog {

_microBlog = microBlog;
//间距
CGFloat margin = 10;
//头像
CGFloat iconW = 40;
CGFloat iconH = 40;
CGFloat iconX = margin;
CGFloat iconY = margin;
_iconFrame = CGRectMake(iconX, iconY, iconW, iconH);

//昵称
CGSize nameSize = [microBlog.name setTextSize:CGSizeMake(MAXFLOAT, MAXFLOAT) andFontSize:NAMEFONT];//取得昵称文字的大小,调用了分类的一个方法
CGFloat nameX = CGRectGetMaxX(_iconFrame) + margin;//X值是头像的最大X值加上间距
CGFloat nameY = (iconH + margin) * 0.5;//Y值是头像的高度加上间距的一半,这里用 * 比用 / 好,速度更快
_nameFrame = CGRectMake(nameX, nameY, nameSize.width, nameSize.height);

//vip
CGFloat vipW = 14;
CGFloat vipH = 14;
CGFloat vipX = CGRectGetMaxX(_nameFrame);//X值是昵称的最大X值
CGFloat vipY = nameY;
if (microBlog.isVip) {//如果模型数据中有vip的数据,才需要定义vip图片的frame
_vipFrame = CGRectMake(vipX, vipY, vipW, vipH);
}

//内容
CGSize textSize = [microBlog.text setTextSize:CGSizeMake(355, MAXFLOAT) andFontSize:TEXTFONT];
CGFloat textX = margin;
CGFloat textY = CGRectGetMaxY(_iconFrame) + margin;//Y值是头像的最大Y值加上间距
_textFrame = CGRectMake(textX, textY, textSize.width, textSize.height);

//图片
CGFloat pictureW = 100;
CGFloat pictureH = 100;
CGFloat pictureX = margin;
CGFloat pictureY = CGRectGetMaxY(_textFrame) + margin;//Y值是内容的最大Y值加上间距
if (microBlog.picture) {//如果模型数据中有微博图片的数据,才需要定义frame
_pictureFrame = CGRectMake(pictureX, pictureY, pictureW, pictureH);
}

//行高
CGFloat textMax = CGRectGetMaxY(_textFrame);//定义一个内容的最大Y值
CGFloat pictureMax = CGRectGetMaxY(_pictureFrame);//定义一个微博图片的最大Y值
_rowHeight = MAX(textMax, pictureMax) + margin;//行高是根据是否有微博图片来决定的。这里的MAX函数其实就是返回一个最大值
}
+ (NSArray *)microBlogFrameList {
NSArray *microBlog = [JWMicroBlog microBlogList];

NSMutableArray *tem = [NSMutableArray array];

for (JWMicroBlog *blog in microBlog) {
JWMicroBlogFrame *frame = [[JWMicroBlogFrame alloc] init];
frame.microBlog = blog;
[tem addObject:frame];
}
return tem;
}
@end


View:

//
//  JWMicroBlogCell.h
//  12-24-MicroBlog
//
//  Created by xiaomoge on 14/12/24.
//  Copyright (c) 2014年 xiaomoge. All rights reserved.
//

#import <UIKit/UIKit.h>
@class JWMicroBlogFrame;
@interface JWMicroBlogCell : UITableViewCell
@property (nonatomic,strong) JWMicroBlogFrame *microBlogFrame;
+ (JWMicroBlogCell *)cellWithTableView:(UITableView *)tableView;
@end


//
//  JWMicroBlogCell.m
//  12-24-MicroBlog
//
//  Created by xiaomoge on 14/12/24.
//  Copyright (c) 2014年 xiaomoge. All rights reserved.
//

#import "JWMicroBlogCell.h"
#import "JWMicroBlogFrame.h"
@interface JWMicroBlogCell ()
@property (nonatomic,weak) UIImageView *iconView;//头像view
@property (nonatomic,weak) UILabel *nameLabel;//昵称view
@property (nonatomic,weak) UIImageView *vipView;//vip图片view
@property (nonatomic,weak) UILabel *textView;//内容view
@property (nonatomic,weak) UIImageView *pictureView;//微博图片view
@end
@implementation JWMicroBlogCell
/*
快速构造一个可重用的cell
*/
+ (JWMicroBlogCell *)cellWithTableView:(UITableView *)tableView {
static NSString *resue = @"bolg";//缓存池标识
JWMicroBlogCell *cell = [tableView dequeueReusableCellWithIdentifier:resue];
if (!cell) {
cell = [[self alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:resue];
}
return cell;
}
/*
重写init方法,添加各控件
*/
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
//头像子控件
UIImageView *icon = [[UIImageView alloc] init];
[self.contentView addSubview:icon];
self.iconView = icon;

//昵称子控件
UILabel *name = [[UILabel alloc] init];
[self.contentView addSubview:name];
self.nameLabel = name;
name.font = [UIFont systemFontOfSize:NAMEFONT];

//vip子控件
UIImageView *vip = [[UIImageView alloc] init];
[self.contentView addSubview:vip];
self.vipView = vip;

//内容子控件
UILabel *text = [[UILabel alloc] init];
[self.contentView addSubview:text];
self.textView = text;
text.numberOfLines = 0;
text.font = [UIFont systemFontOfSize:TEXTFONT];

//图片子控件
UIImageView *picture = [[UIImageView alloc] init];
[self.contentView addSubview:picture];
self.pictureView = picture;
}
return self;
}
/*
重写set方法,设置cell中各控件的内容和frame
*/
- (void)setMicroBlogFrame:(JWMicroBlogFrame *)microBlogFrame {
_microBlogFrame = microBlogFrame;
[self setSubviewsContent];//设置cell中各控件显示的内容
[self setSubviewsFrame];//设置cell中各控件的frame
}
/*
设置cell中各控件显示的内容
*/
- (void)setSubviewsContent {
JWMicroBlog *msg = self.microBlogFrame.microBlog;
self.iconView.image = [UIImage imageNamed:msg.icon];
self.nameLabel.text = msg.name;
if (msg.isVip) {//如果是vip,则昵称颜色设置为红色,否则为黑色
self.vipView.image = [UIImage imageNamed:@"vip"];
self.nameLabel.textColor = [UIColor redColor];
}else {
self.nameLabel.textColor = [UIColor blackColor];
}
self.textView.text = msg.text;
self.pictureView.image = [UIImage imageNamed:msg.picture];
}
/*
设置cell中各控件的frame
*/
- (void)setSubviewsFrame {
self.iconView.frame = self.microBlogFrame.iconFrame;
self.nameLabel.frame = self.microBlogFrame.nameFrame;
self.vipView.frame = self.microBlogFrame.vipFrame;
self.textView.frame = self.microBlogFrame.textFrame;
self.pictureView.frame = self.microBlogFrame.pictureFrame;
}
@end


Controller:

//
//  JWController.m
//  12-24-MicroBlog
//
//  Created by xiaomoge on 14/12/24.
//  Copyright (c) 2014年 xiaomoge. All rights reserved.
//

#import "JWController.h"
#import "JWMicroBlog.h"
#import "JWMicroBlogCell.h"
#import "JWMicroBlogFrame.h"
@interface JWController ()<UITableViewDataSource>
//frame模型数组
@property (nonatomic,strong) NSArray *microBlogFrame;
@end
@implementation JWController
#pragma mark - 懒加载
- (NSArray *)microBlogFrame {
if (!_microBlogFrame) {//如果为空
_microBlogFrame = [JWMicroBlogFrame microBlogFrameList];
}
return _microBlogFrame;
}
#pragma mark - 隐藏状态栏
- (BOOL)prefersStatusBarHidden {
return YES;
}
- (void)viewDidLoad {
[super viewDidLoad];
}
#pragma mark - UITableViewDataSource方法
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.microBlogFrame.count;//返回每组行的多少
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
JWMicroBlogCell *cell = [JWMicroBlogCell cellWithTableView:tableView];
cell.microBlogFrame = self.microBlogFrame[indexPath.row];//取得对应行的数据
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return [self.microBlogFrame[indexPath.row] rowHeight];//返回每行数据的行高
}
@end
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: