第二十四篇:缩合练习代码---简单微博(自定义Cell)

来源:互联网 发布:怪物猎人x 网络联机 编辑:程序博客网 时间:2024/05/01 06:23

1.效果图:


2.写出的详细步骤:

(1)向Main.storyboard里的控制器中添加一个UITableView控件。

(2)ViewController类遵守两个协议(UITableViewDataSource , UITableViewDelegate),并使tableView属性与UITableView控件连线,设置当前控制器成为tableView的数据源对象和代理对象,实现以下方法:

#pragma mark - 数据源方法

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;

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

(3)发现没有数据,那么需要字典转模型;数据模型:QJStatuse;信息模型:QJStatuseFrame。

 》QJStatuse:只有五个属性值对应字典的每个Key。

 》QJStatuseFrame:拥有一个QJStatuse对象(即数据)和每个数据控件的frame。提高性能。

问题:自写一个 计算文字的frame方法:

/** 返回文字真实的Size */- (CGSize) sizeWithText:(NSString *)text Size:(CGSize)size font:(UIFont *)font{        NSDictionary * attrib = @{NSFontAttributeName : font};    return [text boundingRectWithSize:size options:NSStringDrawingUsesLineFragmentOrigin attributes:attrib context:nil].size;}
(4)并发现每个Cell是不一样的,所以需要用代码自定义一个UITableViewCell -->QJStatuseCell继承UITableViewCell。那么QJSatuseCell类必须要提够一些方法,使上面数据源协议的第三个方法可以实现:

 》重写- initWithStyle: reuseIdentifier: 对象方法,用于添加控件。

 》创建一个QJSatuseCell方法, 并调用重写上述方法向QJSatuseCell对象.contentView中添加五个不同的控件(iconImgView,nameLable,vipImgView,text1Lable,pictureImgView),但不设置任何数据,因为该方法只用来创建Cell对象。

  》写出该对象属性_statuseFrame的 setter,用于:根据传入的statuseFrame参数 初始化每个对应Cell内五个控件的:1.内容 2.设置frame

(5)最后每个Cell的高度不一要,那么只要实现代理协议中的一个方法:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{    QJStatuseFrame * sta = self.statuseFrames[indexPath.row];    return sta.cellHeight;}


3.完整代码:

Model:

////  QJStatuse.h//  09-自定义cell-微博////  Created by 瞿杰 on 15/9/30.//#import <UIKit/UIKit.h>@interface QJStatuse : NSObject@property (nonatomic,copy)NSString * icon;@property (nonatomic,copy)NSString * name;@property (nonatomic,copy)NSString * text;@property (nonatomic,copy)NSString * picture;@property (nonatomic,assign)NSNumber * vip;+ (instancetype)statuseWithDictionary:(NSDictionary *)dic;- (instancetype)initWithDictionary:(NSDictionary *)dic;@end

////  QJStatuse.m//  09-自定义cell-微博////  Created by 瞿杰 on 15/9/30.//  Copyright © 2015年 itcast. All rights reserved.//#import "QJStatuse.h"@implementation QJStatuse+ (instancetype)statuseWithDictionary:(NSDictionary *)dic{    return [[self alloc]initWithDictionary:dic];}- (instancetype)initWithDictionary:(NSDictionary *)dic{    if (self = [super init]) {        self.icon = dic[@"icon"];        self.name = dic[@"name"];        self.text = dic[@"text"];        self.picture = dic[@"picture"];        self.vip = dic[@"vip"];    }    return self;}@end


////  QJStatusFrame.h//  09-自定义cell-微博////  Created by 瞿杰 on 15/9/30.//  Copyright © 2015年 itcast. All rights reserved.//#import <Foundation/Foundation.h>#import <UIKit/UIKit.h>@class QJStatuse;@interface QJStatuseFrame : NSObject@property (nonatomic, strong) QJStatuse *statuse;/** *  头像的frame */@property (nonatomic, assign, readonly) CGRect iconFrame;/** *  昵称的frame */@property (nonatomic, assign, readonly) CGRect nameFrame;/** *  会员图标的frame */@property (nonatomic, assign, readonly) CGRect vipFrame;/** *  正文的frame */@property (nonatomic, assign, readonly) CGRect textFrame;/** *  配图的frame */@property (nonatomic, assign, readonly) CGRect pictureFrame;/** *  cell的高度 */@property (nonatomic, assign, readonly) CGFloat cellHeight;@end
////  QJStatuseFrame.m//  09-自定义cell-微博////  Created by 瞿杰 on 15/9/30.//  Copyright © 2015年 itcast. All rights reserved.// 每个QJStatuseFrame对象都拥有 每个控件的 信息 和 frame#import "QJStatuseFrame.h"#import "QJStatuse.h"#define nameFont [UIFont systemFontOfSize:14]#define textFont [UIFont systemFontOfSize:16]@implementation QJStatuseFrame/** 属性_statuse的setter方法 */- (void)setStatuse:(QJStatuse *)statuse{        //每个控件的信息    _statuse = statuse ;        //间隔    CGFloat padding = 10 ;        //iconFrame    CGFloat iconX = padding ;    CGFloat iconY = padding ;    CGFloat iconW = 50;    CGFloat iconH = 50;    _iconFrame = CGRectMake(iconX, iconY, iconW, iconH);        //nameFrame    CGSize nameSize = [self sizeWithText:self.statuse.name Size:CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX) font:nameFont];    CGFloat nameX = CGRectGetMaxX(self.iconFrame) + padding;    CGFloat nameY = self.iconFrame.origin.y + (self.iconFrame.size.height - nameSize.height)*0.5;    _nameFrame = CGRectMake(nameX, nameY, nameSize.width, nameSize.height);        //vipFrame    CGFloat vipX = CGRectGetMaxX(self.nameFrame) + padding;    CGFloat vipY = self.nameFrame.origin.y ;    CGFloat vipW = 14;    CGFloat vipH = 14;    _vipFrame = CGRectMake(vipX, vipY, vipW, vipH);        //正文textFrame    CGFloat textX = padding ;    CGFloat textY = CGRectGetMaxY(self.iconFrame) + padding;    CGSize textSize = [self sizeWithText:self.statuse.text Size:CGSizeMake(394, CGFLOAT_MAX) font:textFont];    _textFrame = CGRectMake(textX, textY, textSize.width, textSize.height);        //符加图pictureFrame    if (self.statuse.picture ) {        CGFloat pictureX = padding ;        CGFloat pictureY = CGRectGetMaxY(self.textFrame);        CGFloat pictureW = 100;        CGFloat pictureH = 100;        _pictureFrame = CGRectMake(pictureX, pictureY, pictureW, pictureH);                _cellHeight = CGRectGetMaxY(self.pictureFrame) + padding;    }    else{        _pictureFrame = CGRectZero ;        _cellHeight = CGRectGetMaxY(self.textFrame) + padding;    }}/** 返回文字真实的Size */- (CGSize) sizeWithText:(NSString *)text Size:(CGSize)size font:(UIFont *)font{        NSDictionary * attrib = @{NSFontAttributeName : font};    return [text boundingRectWithSize:size options:NSStringDrawingUsesLineFragmentOrigin attributes:attrib context:nil].size;}@end


View:
////  QJStatuseCell.h//  09-自定义cell-微博////  Created by 瞿杰 on 15/9/30.//  Copyright © 2015年 itcast. All rights reserved.//#import <UIKit/UIKit.h>@class QJStatuseFrame;@interface QJStatuseCell : UITableViewCell@property (nonatomic , weak)QJStatuseFrame * statuseFrame;+ (instancetype)statuseCellWithTableView:(UITableView *)tableView;@end
////  QJStatuseCell.m//  09-自定义cell-微博////  Created by 瞿杰 on 15/9/30.//  Copyright © 2015年 itcast. All rights reserved.//#import "QJStatuseCell.h"#import "QJStatuseFrame.h"#import "QJStatuse.h"#define nameFont [UIFont systemFontOfSize:14]#define textFont [UIFont systemFontOfSize:16]@interface QJStatuseCell ()@property (nonatomic , weak)UIImageView * iconImgView ;@property (nonatomic , weak)UILabel * nameLable ;@property (nonatomic , weak)UIImageView * vipImgView ;@property (nonatomic , weak)UILabel * text1Lable ;@property (nonatomic , weak)UIImageView * pictureImgView ;@end@implementation QJStatuseCell+ (instancetype)statuseCellWithTableView:(UITableView *)tableView{    // 可重用的标识符    NSString * ID = @"statuseCell";    QJStatuseCell * cell = [tableView dequeueReusableCellWithIdentifier:ID];    if (cell == nil) {        cell = [[self alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];    }    return cell;}/** 重写从父类继承的对象方法:只添加控件,不设置任何数据,因为数据是不确定的 */- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];    if (self) {        //添加头象        UIImageView * iconImgView = [[UIImageView alloc]init];        [self.contentView addSubview:iconImgView];        self.iconImgView = iconImgView;                //添加nameLable        UILabel * nameLable = [[UILabel alloc]init];        nameLable.font = nameFont;        [self.contentView addSubview:nameLable];        self.nameLable = nameLable;                //添加vipImgView        UIImageView * vipImgView = [[UIImageView alloc]init];        [self.contentView addSubview:vipImgView];        self.vipImgView = vipImgView;                //添加text1Lable        UILabel * textLalbe = [[UILabel alloc]init];        textLalbe.font = textFont ;        textLalbe.numberOfLines = 0; // 不限制行数,自动换行        [self.contentView addSubview:textLalbe];        self.text1Lable = textLalbe ;                        //添加pictureImgView        UIImageView * pictureImgView = [[UIImageView alloc]init];        [self.contentView addSubview:pictureImgView];        self.pictureImgView = pictureImgView ;    }    return self ;}/** *   初始化每个对应Cell内五个控件的:1.内容 2.设置frame */- (void)setStatuseFrame:(QJStatuseFrame *)statuseFrame{        _statuseFrame = statuseFrame;        // 初始化头象    self.iconImgView.image = [UIImage imageNamed:statuseFrame.statuse.icon];    self.iconImgView.frame = statuseFrame.iconFrame;        // 初始化nameLable    self.nameLable.text = statuseFrame.statuse.name;    self.nameLable.frame = statuseFrame.nameFrame;        // 初始化vipImgView    if ([statuseFrame.statuse.vip intValue]) {        self.nameLable.textColor = [UIColor redColor];        self.vipImgView.hidden = NO;        self.vipImgView.image = [UIImage imageNamed:@"vip"];        self.vipImgView.frame = statuseFrame.vipFrame;    }    else{        self.nameLable.textColor = [UIColor blackColor];        self.vipImgView.hidden = YES ;    }        // 初始化textLable    self.text1Lable.text = statuseFrame.statuse.text;    self.text1Lable.frame = statuseFrame.textFrame;        // 初始化pictureImgView,    // 无需判断是否需要隐藏,因为如果没有图,那么pictureFrame = CGRectZero    self.pictureImgView.image = [UIImage imageNamed:statuseFrame.statuse.picture];    self.pictureImgView.frame = statuseFrame.pictureFrame;    }//- (void)awakeFromNib {//    // Initialization code//}////- (void)setSelected:(BOOL)selected animated:(BOOL)animated {//    [super setSelected:selected animated:animated];////    // Configure the view for the selected state//}@end

Controller:

////  ViewController.h//  09-自定义cell-微博////  Created by 瞿杰 on 15/9/30.//  Copyright © 2015年 itcast. All rights reserved.//#import <UIKit/UIKit.h>@interface ViewController : UIViewController@end
////  ViewController.m//  09-自定义cell-微博////  Created by 瞿杰 on 15/9/30.//  Copyright © 2015年 itcast. All rights reserved.//#import "ViewController.h"#import "QJStatuse.h"#import "QJStatuseFrame.h"#import "QJStatuseCell.h"@interface ViewController ()<UITableViewDataSource , UITableViewDelegate>@property (weak, nonatomic) IBOutlet UITableView *tableView;@property (strong,nonatomic)NSArray * statuseFrames;@end@implementation ViewController- (void)viewDidLoad {    [super viewDidLoad];        // 设置数据源    self.tableView.dataSource = self;    self.tableView.delegate = self ;}- (BOOL)prefersStatusBarHidden{    return YES;}- (NSArray *)statuseFrames{    if (_statuseFrames == nil) {        NSString * path = [[NSBundle mainBundle]pathForResource:@"statuses.plist" ofType:nil];        NSArray * statuArray = [NSArray arrayWithContentsOfFile:path];        NSMutableArray * statuseFrames = [NSMutableArray array];        for(NSDictionary * dic in statuArray){            QJStatuse * stat = [QJStatuse statuseWithDictionary:dic];            QJStatuseFrame * statFrame = [[QJStatuseFrame alloc]init];            statFrame.statuse = stat ;            [statuseFrames addObject:statFrame];        }        _statuseFrames = statuseFrames;    }    return _statuseFrames;}#pragma mark - 数据源方法- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{    return 1;}- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{    return self.statuseFrames.count;}- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{    // 创建一个cell    QJStatuseCell * cell = [QJStatuseCell statuseCellWithTableView:tableView];        //初始化内容    cell.statuseFrame = self.statuseFrames[indexPath.row];        return cell;}#pragma mark - 代理方法- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{    QJStatuseFrame * sta = self.statuseFrames[indexPath.row];    return sta.cellHeight;}@end





0 0
原创粉丝点击