UI020: UITableView 微博02

封装frame模型:优化代码,在懒加载数据的时候,计算好每个控件的frame和 cell的行高。

CZWeibo.m

// CZWeibo.h
@interface CZWeibo :NSObject
@property(nanotomic, copy) NSString *text;
@property(nanotomic, copy) NSString *icon;
@property(nanotomic, copy) NSString *picture;
@property(nanotomic, copy) NSString *name;
@property(nanotomic, assign, getter=isVip) BOOL vip;

- (instancetype)initWithDict:(NSDictionary *)dict;
+ (instancetype)weiboWithDict:(NSDictionary *)dict;
@end
//-----------------------
// CZWeibo.m
- (instancetype)initWithDict:(NSDictionary *)dict{
    // TODO
}
+ (instancetype)weiboWithDict:(NSDictionary *)dict{
    // TODO
}

//-----------------------

@class CZWeibo;
@interface CZWeiboFrame : NSObject
@property(nanotomic, strong) CZWeibo *weibo; // 重写setter方法。
// 用来保存头像的frame
@property(nanotomic, assign, readonly) CGRect iconFrame;
@property(nanotomic, assign, readonly) CGRect nameFrame;
@property(nanotomic, assign, readonly) CGRect vipFrame;
@property(nanotomic, assign, readonly) CGRect textFrame;
@property(nanotomic, assign, readonly) CGRect picFrame;
// 行高
@property(nanotomic, assign, readonly) int rowHeight;
@end

//-----------------------
// 自定义字体的宏
#import "CZWeiboFrame.h"
#import <UIKit/UIKit.h>
#define nameFont [UIFont systemFontOfSize:12];
#define textFont [UIFont systemFontOfSize:14];

@implementation CZWeiboFrame
// 重写weibo的set方法,在里面计算frame
- (void)setWeibo:(CZWeibo *) weibo
{
    _weibo = weibo;
    // 计算每个控件的frame,宽高。
    CGFloat margin = 10;
    CZModel *model = self.weibo;
    // 1.头像
    CGFloat iconW = 35;
    CGFloat iconH = 35;
    CGFloat iconX = margin;
    CGFloat iconY = margin;
    _iconFrame = CGRectMake(iconX, iconY, iconW, iconH);
    
    // 2.昵称
    CGFloat nameX = CGRectGetMaxX(_iconFrame) + margin;
    // 根据文字内容,动态计算label的高+宽
    NSString *nickName = model.name; // 昵称
    NSDictionary *attr = @{NSFontAttributeName: nameFont}; // 字体字典
    // CGSize nameSize = [nickName boundingRectWithSize:CGSizeMake(MAXFLOAT, MAXFLOAT) options: NSStringDrawingUsesLineFragmentOrigin  attributes: attr   context:nil].size; // 获得文字显示的宽高
    CGSize nameSize = [self sizeWithText:nickName andMaxSize:CGSizeMake(MAXFLOAT, MAXFLOAT) andFont:nameFont];

    CGFloat nameW = nameSize.width;
    CGFloat nameH = nameSize.height;
    CGFloat nameY = iconY + (iconH - nameH) / 2;
    _nameFrame = CGRectMake(nameX, nameY, nameW, nameH);

    // 3.会员
    CGFloat vipW = 10;
    CGFloat vipH = 10;
    CGFloat vipX = CGRectGetMaxX(_nameFrame) + margin;
    CGFloat vipY = nameY;
    _vipFrame = CGRectMake(vipX, vipY, vipW, vipH);

    // 4.正文
    CGFloat textX = iconX;
    CGFloat textY = CGRectGetMaxX(self.imgViewIcon.frame) + margin;
    CGSize textSize = [self sizeWithText:weibo.text andMaxSize:CGSizeMake(300, MAXFLOAT) andFont:textFont];
    CGFloat textW = textSize.width;
    CGFloat textH = textSize.height;
    _textFrame = CGRectMake(textX, textY, textW, textH);

    // 5.配图
    CGFloat picW = 100;
    CGFloat picH = 100;
    CGFloat picX = iconX;
    CGFloat picY = CGRectGetMaxY(_textFrame) + margin;
    _picFrame = CGRectMake(picX, picY, picW, picH);

    // 6.计算每行的高度。
    CGFloat rowHeight = 0;
    if(model.picture) {
        // 行高 = 配图的maxY + margin
        rowHeight = CGRectGetMaxY(_picFrame) + margin;
    } else {
        // 行高 = 正文的maxY + margin
        rowHeight = CGRectGetMaxY(_textFrame) + margin;
    }
    // 给行高赋值。
    _rowHeight = rowHeight;
}

// 根据给定的字符串,最大值的size,给定的字体。计算文字占据的大小。
- (CGSize)sizeWithText:(NSString *)text andMaxSize:(CGSize)maxSize andFont:(UIFont *) font {
    NSDictionary *attr = @{NSFontAttributeName: font}; // 字体字典
    return  [text boundingRectWithSize:maxSize options: NSStringDrawingUsesLineFragmentOrigin 
    attributes: attr  context:nil].size; 
}
@end

自定义Cell01创建子控件:CZWeiboCell

// CZWeiboCell.h
#import <UIKit/UIKit.h>
@class CZWeiboFrame
@interface CZWeiboCell : UITableViewCell
// @property(nonatomic, strong) CZWeibo *weibo;
@property(nonatomic, strong) CZWeiboFrame *weiboFrame;

+ (instancetype)weiboCellWithTableView:(UITableView *)tableView;
@end

//---------------------
// CZWeiboCell.m
#import "CZWeiboCell.h"
#import "CZWeibo.h"

// 自定义字体的宏
#define nameFont [UIFont systemFontOfSize:12];
#define textFont [UIFont systemFontOfSize:14];

@interface CZWeiboCell ()
@property (nonatomic, weak) UIImageView *imgViewIcon;
@property (nonatomic, weak) UILabel *lblNickName;
@property (nonatomic, weak) UIImageView *imgViewVip;
@property (nonatomic, weak) UILabel *lblText;
@property (nonatomic, weak) UIImageView *imgViewPicture;
@end

@implementation CZWeiboCell
+(instancetype)weiboCellWithTableView:(UITableView *)tableView
{
    static NSString *ID = @"weibo_cell";
    CZWeiboCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    if(cell == nil) {
        cell = [[CZWeiboCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
    }
    return cell;
}

// 数据模型,改变成Frame模型。
- (void)setWeibo:(CZWeiboFrame *)weiboFrame {
    _weiboFrame = weiboFrame;
    // 设置子控件的数据
    [self settingData];
    // 设置子控件frame
    [self settingFrame];
} 
// 设置数据的方法
-(void)settingData {
    CZModel *model = self.weiboFrame.weibo;
    //  (头像,昵称,会员,正文,配图)
    self.imgViewIcon.image = [UIImage imageNamed:model.icon];
    self.lblNickName.text = model.name;
    // 会员图标:显示或 不显示
    if(model.isVip) {
        self.imageViewVip.hidden = NO;
    } else {
        self.imageViewVip.hidden = YES;
    }
    self.lblText.text = model.text;
    // 配图,有配图就显示;无配图不设置,也不显示。
    if(model.picture) {
        self.imgViewPicture.image = [UIImage imageNamed:model.picture];
        self.imageViewVip.hidden = NO;
    } else { // 没配图。隐藏配图框。
        self.imageViewVip.hidden = YES;
    }
}
// 设置子控件frame
-(void)settingFrame {
    self.imgViewIcon.frame = self.weiboFrame.iconFrame;
    self.lblNickName.frame = self.weiboFrame.nameFrame;
    self.imageViewVip.frame = self.weiboFrame.vipFrame;
    self.lblText.frame = self.weiboFrame.textFrame;
    self.imgViewPicture.frame = self.weiboFrame.picFrame;
}

// 重写方法
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier 
{
    // 调用父类的方法,保证父类的方法被执行
    if(self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
        //  创建5个子控件(头像,昵称,会员,正文,配图)
        UIImageView *imgViewIcon = [[UIImageView alloc] init];
        [self.contentView addSubView:imgViewIcon]
        self.imgViewIcon = imgViewIcon; // 关联到cell中。

        UILabel *lblNickName = [[UILabel alloc] init];
        lblNickName.font = nameFont;
        [self.contentView addSubView:lblNickName];
        self.lblNickName = lblNickName;

        UIImageView *imgViewVip = [[UIImageView alloc] init];
        // vip图标,直接写死,所有vip用户的图标相同。
        imgViewVip.image = [UIImage imageNamed:@"vip"];
        [self.contentView addSubView:imgViewVip];
        self.imgViewVip = imgViewVip;

        UILabel *lblText = [[UILabel alloc] init];
        lblText.font = textFont;
        lblText.numberOfLines = 0; // 自动换行
        self.lblText = lblText;
        [self.contentView addSubView:lblText];

        UIImageView *imgViewPicture = [[UIImageView alloc] init];
        [self.contentView addSubView:imgViewPicture];
        self.imgViewPicture = imgViewPicture;
    }
    return self;
}

- (void)awakeFromNib {
}
@end

#import "CZTableViewController.h"
@interface CZTableViewController ()
// 保存了CZWeiboFrame模型,而不是CZWeibo模型。
@property (nonatomic, strong) NSArray *weiboFrames;
@end

@implementation CZTableViewController
-(NSArray *) weiboFrames {
    if(_weiboFrames == nil) {
        NSString *path = [[NSBundle mainBundle] pathForResource:@"weibos.plist" ofType:nil];
        NSArray *arrayDict = [NSArray arrayWithContentsOfFile:path];
        NSMutableArray *arrayModels = [NSMutableArray array];
        for(NSDictionary *dict in arrayDict) {
            CZWeibo *model = [CZWeibo weiboWithDict:dict];  
            // 创建一个空的模型。  
            CZWeiboFrame *modelFrame = [[CZWeiboFrame alloc] init];
            modelFrame.weibo = model;
            [arrayModels addObject:modelFrame];
        }
        _weiboFrames = arrayModels;
    }
    return _weiboFrames;
}


// 懒加载数据,计算每行的行高。所有子控件的frame,
-(NSArray *) weibos {
    if(_weibos ==nil) {
        NSString *path = [[NSBundle mainBundle] pathForResource:@"weibos.plist" ofType:nil];
        NSArray *arrayDict = [NSArray arrayWithContentsOfFile:path];
        NSMutableArray *arrayModels = [NSMutableArray array];
        for(NSDictionary *dict in arrayDict) {
            CZWeibo *model = [CZWeibo weiboWithDict:dict];
            [arrayModels addObject:model];
        }
        _weibos = arrayModels;
    }
    return _weibos;
}

-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger) section
{
    return self.weiboFrames.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    // 1. 获取数据模型
    CZWeiboCell *model = self.weiboFrames[indexPath.row];
    // 2. 创建单元格。
    /* static NSString *ID = @"weibo_cell";
    CZWeiboCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    if(cell == nil) {
        cell = [[CZWeiboCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
    } */
    CZWeiboCell *cell = [CZWeiboCell weiboCellWithTableView:tableView];

    cell.weiboFrame = model; // 3.设置单元格数据
    return cell; // 4.返回单元格
}

// 返回每行的行高。
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 
{
    CZWeiboFrame *weiboFrame = self.weiboFrames[indexPath.row];
    return weiboFrame.rowHeight;
}

- (void)viewDidLoad {
    [super viewDidLoad];
}
@end

计算昵称的frame:
CGSize nameSize = [字符串对象 boundingRectWithSize:CGSizeMake(MAXFLOAT, MAXFLOAT) options: NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:font} context:nil];



2023/05/30 周二

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 第15章[https://zhongyong.5000yan.com/15/] 君子之道,辟如行远必自迩,辟如登高...
    竹筠益阅读 669评论 0 0
  • 今日体验206 眼前有一只迷人的小布偶猫,全身雪白,两只耳朵,鼻尖,还有四肢爪是浅灰色。 它在我眼前呈现出一...
    手心捧月阅读 861评论 0 0
  • 低段数学教学要注重激发学生兴趣,注重提供思维支架,注重思想有机渗透。
    吱欧邹的邹阅读 431评论 0 0
  • 2023.5.16 星期二 天气晴 1820 天气依旧闷热,貌似带着高兴的心情一下子跳跃了夏天,猝不及防我们...
    燕的呢喃阅读 606评论 0 0
  • 、、同学是班上头疼的孩子,不遵守课堂纪律,学习没有状态,令很多老师头疼,跟家长沟通多次无果。对于孩子软硬不吃。我常...
    暖暖_a004阅读 393评论 0 0