UITableViewCell之微博篇

微博篇

本应用所涉及的知识点:

  • 1.UITableView 中的cell
  • 2.模型的创建
  • 3.MJExtension第三方框架的使用

需求分析

  • 1.界面分析

    • 微博界面
    • 界面控件分析:
      • 整个页面

        • 1.不难知道,界面是由若干个子cell组成的,并且每个子cell的高度都不同,高度都是由内容来定.
        • 2.子模块的控件数不一样,有的是有五个子控件,有的有四个子控件,而有的只有三个.
        • 3.子控件的类型分别是:头像(UIImageView),昵称(UILabel),Vip(UIImageView),微博正文(UILabel)和配图(UIImageView).
      • 各个子模块
        • 1.子控件个数:每个模块的控件数都不一定一样,但是考虑到实现功能的时候能够快速方便的实现,所以在声明属性的时候,我们还是选择五个控件.
        • 2.子控件的高度:由界面可知,整个子控件的高度只与图标,微博正文和配图(不一定有)有关.
        • 3.在进行加载时,就需要先判断是否是Vip和是否有配图,然后再进行加载.
  • 2.功能分析

    • 整体功能

      • 用户能够根据自己的心情上传微博正文和配图,并能够在界面上浏览其他人的微博内容.
    • 子控件功能
      • 根据每个人的账户数据不同来展示头像,昵称和是否是会员,并加载微博正文和是否有配图.

程序的实现

界面的实现

界面初实现

    • 1.主控件ViewController
      • 首先将h文件中的UIViewController改为UITableViewController

        #import <UIKit/UIKit.h>
        @interface ViewController : UITableViewController
        @end
        
      • 然后再在main.storyboard中设置
    • 2.再创建分类,继承UITableViewCell,例如ZYQStatusCell
    • 2.1UITableViewCell.h文件
      #import <UIKit/UIKit.h>
      @class ZYQStatus;
      @interface ZYQStatusCell : UITableViewCell
      @end
      
    • 2.2在UITableViewCell.m文件中重写initWithStyle方法创建各个子控件并添加到父控件contentSize中,并在layoutSubviews方法中设置各个子控件的位置.
#import "ZYQStatusCell.h"
@interface ZYQStatusCell ()
/** 图像*/
@property (nonatomic ,weak)UIImageView *iconImageView;
/** 昵称*/
@property (nonatomic ,weak)UILabel *nameLabel;
/** vip*/
@property (nonatomic ,weak)UIImageView *vipImageView;
/** 正文*/
@property (nonatomic ,weak)UILabel *text_Label;
/** 配图*/
@property (nonatomic ,weak)UIImageView *pictureImageView;
@end
@implementation ZYQStatusCell
// 把有可能显示的子控件都添加进去
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
        /** 图像*/
        UIImageView *iconImageView = [[UIImageView alloc]init];
       iconImageView.backgroundColor = [UIColor redColor];
        [self.contentView addSubview:iconImageView];
        self.iconImageView = iconImageView;

        /** 昵称*/
        UILabel *nameLabel = [[UILabel alloc]init];
      nameLabel.backgroundColor = [UIColor yellowColor];
        [self.contentView addSubview:nameLabel];
        self.nameLabel = nameLabel;

        /** vip*/
        UIImageView *vipImageView = [[UIImageView alloc] init];
       vipImageView.backgroundColor = [UIColor greenColor];
        [self.contentView addSubview:vipImageView];
        self.vipImageView = vipImageView;

        /** 配图*/
        UIImageView *pictureImageView = [[UIImageView alloc] init];
      pictureImageView.backgroundColor = [UIColor grayColor];
        [self.contentView addSubview:pictureImageView];
        self.pictureImageView = pictureImageView;

        /** 正文*/
        UILabel *text_Label = [[UILabel alloc] init];
       text_Label.backgroundColor = [UIColor blueColor];
        [self.contentView addSubview:text_Label];
        self.text_Label = text_Label;
    }
    return self;
}
//设置各控件的位置
- (void)layoutSubviews
{
    [super layoutSubviews];
    CGFloat space = 10;
    /** 图像*/
    CGFloat iconX = space;
    CGFloat iconY = space;
    CGFloat iconWH = 40;
    self.iconImageView.frame = CGRectMake(iconX, iconY, iconWH, iconWH);
    /* 昵称*/
    CGFloat nameX = CGRectGetMaxX(self.iconImageView.frame) + space;
    CGFloat nameY = iconY;
    CGFloat nameW = nameSize.width;
    CGFloat nameH = nameSize.height;
    self.nameLabel.frame = CGRectMake(nameX, nameY, nameW, nameH);
    /** vip*/
        CGFloat vipW = 14;
        CGFloat vipH = nameH;
        CGFloat vipX = CGRectGetMaxX(self.nameLabel.frame) + space;
        CGFloat vipY = nameY;
        self.vipImageView.frame = CGRectMake(vipX, vipY, vipW, vipH);
    /** 正文*/
    CGFloat textX = iconX;
    CGFloat textY = CGRectGetMaxY(self.iconImageView.frame) + space;
    CGFloat textW = self.contentView.frame.size.width - 2 * space;
    self.text_Label.frame = CGRectMake(textX, textY, textW, textH);
    // 配图
        CGFloat pictureX = textX;
        CGFloat pictureY = CGRectGetMaxY(self.text_Label.frame) + space;
        CGFloat pictureWH = 100;
        self.pictureImageView.frame = CGRectMake(pictureX, pictureY, pictureWH, pictureWH);

}
    • 在主控件文件中,只需要实现相对应的代理方法
#import "ViewController.h"
#import "ZYQStatusCell.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.tableView.rowHeight = 250;

}

#pragma mark - 数据源方法

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return 20;
}
- (UITableViewCell *)tableView:(UITableView *)tableView
   cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [[UITableViewCell alloc]init];
    return cell;
}
@end
  • 运行结果:

功能的实现

数据内容的加载

  • 为了能够使得程序能够更加简单,就需要创建模型,例如:ZYQStatus,此时就需要声明各个子控件的属性.
#import <Foundation/Foundation.h>
@interface ZYQStatus : NSObject

/** 图像*/
@property(nonatomic, copy)NSString *icon;

/** 昵称*/
@property(nonatomic, copy)NSString *name;

/** 正文*/
@property(nonatomic, copy)NSString *text;

/** vip*/
@property(nonatomic, assign,getter=isVip)BOOL vip;

/** 配图*/
@property(nonatomic, copy)NSString *picture;
@end
  • 同时在UITableViewCell.h文件中,也需要声明一个微博模型
#import <UIKit/UIKit.h>

@class ZYQStatus;

@interface ZYQStatusCell : UITableViewCell

/** 微博模型*/
@property(nonatomic, strong)ZYQStatus *status;

@end
  • 同时在UITableViewCell.m文件中,就需要重写微博模型的set方法
#import "ZYQStatusCell.h"
#import "ZYQStatus.h"

#define ZYQTextFont [UIFont systemFontOfSize:14]
#define ZYQNameFont [UIFont systemFontOfSize:17]

@interface ZYQStatusCell ()
/** 图像*/
@property (nonatomic ,weak)UIImageView *iconImageView;
/** 昵称*/
@property (nonatomic ,weak)UILabel *nameLabel;
/** vip*/
@property (nonatomic ,weak)UIImageView *vipImageView;
/** 正文*/
@property (nonatomic ,weak)UILabel *text_Label;
/** 配图*/
@property (nonatomic ,weak)UIImageView *pictureImageView;

@end

@implementation ZYQStatusCell

// 把有可能显示的子控件都添加进去
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
        /** 图像*/
        UIImageView *iconImageView = [[UIImageView alloc]init];
        iconImageView.backgroundColor = [UIColor redColor];
        [self.contentView addSubview:iconImageView];
        self.iconImageView = iconImageView;

        /** 昵称*/
        UILabel *nameLabel = [[UILabel alloc]init];
        nameLabel.backgroundColor = [UIColor yellowColor];
        nameLabel.font = ZYQNameFont;
        [self.contentView addSubview:nameLabel];
        self.nameLabel = nameLabel;

        /** vip*/
        UIImageView *vipImageView = [[UIImageView alloc] init];
        vipImageView.contentMode = UIViewContentModeCenter;
        vipImageView.backgroundColor = [UIColor greenColor];
        vipImageView.image = [UIImage imageNamed:@"vip"];
        [self.contentView addSubview:vipImageView];
        self.vipImageView = vipImageView;

        /** 配图*/
        UIImageView *pictureImageView = [[UIImageView alloc] init];
        pictureImageView.backgroundColor = [UIColor grayColor];
        [self.contentView addSubview:pictureImageView];
        self.pictureImageView = pictureImageView;

        /** 正文*/
        UILabel *text_Label = [[UILabel alloc] init];
        text_Label.backgroundColor = [UIColor blueColor];
        text_Label.font = ZYQTextFont;
        text_Label.numberOfLines = 0;
        [self.contentView addSubview:text_Label];
        self.text_Label = text_Label;

    }
    return self;

}

//设置各控件的位置
- (void)layoutSubviews
{
    [super layoutSubviews];
    CGFloat space = 10;
    /** 图像*/
    CGFloat iconX = space;
    CGFloat iconY = space;
    CGFloat iconWH = 40;
    self.iconImageView.frame = CGRectMake(iconX, iconY, iconWH, iconWH);

    /* 昵称*/
    CGFloat nameX = CGRectGetMaxX(self.iconImageView.frame) + space;
    CGFloat nameY = iconY;

    // 计算昵称文字的尺寸
    NSDictionary *nameAtt = @{NSFontAttributeName : ZYQNameFont};
    CGSize nameSize = [self.status.name sizeWithAttributes:nameAtt];
    CGFloat nameW = nameSize.width;
    CGFloat nameH = nameSize.height;
    self.nameLabel.frame = CGRectMake(nameX, nameY, nameW, nameH);

    /** vip*/
    if (self.status.isVip) {
        CGFloat vipW = 14;
        CGFloat vipH = nameH;
        CGFloat vipX = CGRectGetMaxX(self.nameLabel.frame) + space;
        CGFloat vipY = nameY;
        self.vipImageView.frame = CGRectMake(vipX, vipY, vipW, vipH);
    }

    /** 正文*/
    CGFloat textX = iconX;
    CGFloat textY = CGRectGetMaxY(self.iconImageView.frame) + space;
    CGFloat textW = self.contentView.frame.size.width - 2 * space;
    NSDictionary *textArr = @{NSFontAttributeName : ZYQTextFont};
    CGSize textMaxSize = CGSizeMake(textW, MAXFLOAT);
    CGFloat textH = [self.status.text boundingRectWithSize:textMaxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:textArr context:nil].size.height;
    self.text_Label.frame = CGRectMake(textX, textY, textW, textH);

    if (self.status.picture) { // 有配图
        CGFloat pictureX = textX;
        CGFloat pictureY = CGRectGetMaxY(self.text_Label.frame) + space;
        CGFloat pictureWH = 100;
        self.pictureImageView.frame = CGRectMake(pictureX, pictureY, pictureWH, pictureWH);
    }

}

//重写status的set方法
- (void)setStatus:(ZYQStatus *)status
{
    _status = status;
    //设置头像
    self.iconImageView.image = [UIImage imageNamed:status.icon];
    //设置昵称
    self.nameLabel.text = status.name;
    //设置是否vip
    if (status.isVip) {
        self.vipImageView.hidden = NO;
        self.nameLabel.textColor = [UIColor orangeColor];
    }
    else
    {
        self.vipImageView.hidden = YES;
        self.nameLabel.textColor = [UIColor blackColor];
    }
    //设置正文
    self.text_Label.text = status.text;

    //设置配图
    if (status.picture) {
        self.pictureImageView.hidden = NO;
        self.pictureImageView.image = [UIImage imageNamed:status.picture];
    }
    else
    {
        self.pictureImageView.hidden = YES;
    }

}
@end
  • 在主控件文件中,只需要实现相对应的代理方法.在加载数据时,为了更好地将字典转换成模型,我们就使用了MJExtension框架.
#import "ViewController.h"
#import "ZYQStatus.h"
#import "ZYQStatusCell.h"
#import "MJExtension.h"

@interface ViewController ()
//所有微博数据
@property(nonatomic,strong)NSArray *statuses;
@end

@implementation ViewController
//懒加载
- (NSArray *)statuses
{
    if (!_statuses) {
        _statuses = [ZYQStatus mj_objectArrayWithFilename:@"statuses.plist"];
    }
    return _statuses;
}

  NSString *ID = @"status";

- (void)viewDidLoad {
    [super viewDidLoad];

    //注册cell
    [self.tableView registerClass:[ZYQStatusCell class] forCellReuseIdentifier:ID];
    self.tableView.rowHeight = 250;

}

#pragma mark - 数据源方法

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return self.statuses.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView
   cellForRowAtIndexPath:(NSIndexPath *)indexPath
{

    //访问缓存池
    ZYQStatusCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    //设置数据
    cell.status = self.statuses[indexPath.row];

    return cell;
}
@end
  • 运行结果:
  • 结果分析:
    • 整体界面实现了功能,但是还有明显的不足,就是高度是固定的,所以就得进行优化,动态计算高度.
    • 由于在加载子控件的时候,先计算出cell的高度后才会加载子控件,所以在加载子控件之前就得计算好高度.
    • 解决方案:在这个方法返回之前计算好cell的高度
// 方案:在这个方法返回之前计算好cell的高度
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    ZYQStatus *status = self.statuses[indexPath.row];

    CGFloat space = 10;
    /** 图像*/
    CGFloat iconX = space;
    CGFloat iconY = space;
    CGFloat iconWH = 40;
    CGRect iconImageViewFrame = CGRectMake(iconX, iconY, iconWH, iconWH);

    /** 正文*/
    CGFloat textX = iconX;
    CGFloat textY = CGRectGetMaxY(iconImageViewFrame) + space;
    CGFloat textW = [UIScreen mainScreen].bounds.size.width - 2 * space;
    NSDictionary *textArr = @{NSFontAttributeName : [UIFont systemFontOfSize:14]};
    CGSize textMaxSize = CGSizeMake(textW, MAXFLOAT);
    CGFloat textH = [status.text boundingRectWithSize:textMaxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:textArr context:nil].size.height;
    CGRect text_LabelFrame = CGRectMake(textX, textY, textW, textH);

    CGFloat cellH = 0;
    if (status.picture) { // 有配图
        CGFloat pictureX = textX;
        CGFloat pictureY = CGRectGetMaxY(text_LabelFrame) + space;
        CGFloat pictureWH = 100;
        CGRect pictureImageViewFrame = CGRectMake(pictureX, pictureY, pictureWH, pictureWH);
        cellH = CGRectGetMaxY(pictureImageViewFrame) + space;
    } else {
        cellH = CGRectGetMaxY(text_LabelFrame) + space;
    }
    return cellH;

}
  • 另外:在viewDidLoad中就不需要给每一行cell的高度赋值.
- (void)viewDidLoad {
    [super viewDidLoad];

    //注册cell
    [self.tableView registerClass:[ZYQStatusCell class] forCellReuseIdentifier:ID];

}
  • 运行结果:

总结:

难点
  • 难点之一:动态计算每一个cell的高度.
  • 难点之二:在加载子控件的时候,有的需要先进行判断在决定是否添加.
注意点
  • 注意点1:在main.storyboard中,需要将UITableViewController的class设置为ViewController,并设置为程序加载启动界面.
  • 注意点2:在计算昵称的高度时,需要在创建nameLabel控件时指定字体类型,同时在layoutSubViews方法计算高度时,也需要指定同种类型.
  • 注意点3:在计算微博正文的高度时,需要在创建TextLabel控件的时候,指定字体类型,同时还得指定最大宽度.
时间: 2024-10-05 04:58:43

UITableViewCell之微博篇的相关文章

UITableViewcell实现微博界面

一.实现效果 二.使用纯代码自定义一个tableview的步骤 1.新建一个继承自UITableViewCell的类 2.重写initWithStyle:reuseIdentifier:方法 添加所有需要显示的子控件(不需要设置子控件的数据和frame,  子控件要添加到contentView中) 进行子控件一次性的属性设置(有些属性只需要设置一次, 比如字体\固定的图片) 3.提供2个模型 数据模型: 存放文字数据\图片数据 frame模型: 存放数据模型\所有子控件的frame\cell的高

在自己的App里面加入微博分享---Android平台

现在的App,如果是想留住用户,单纯的用本App的账户用户名已经很难达到目的,就像网站一样,查看网站内容需要注册账户登录后才能查看,如果不是很感兴趣的内容,一般就直接选择点击网页旁边的小红叉关掉网页.App也是这样的情况,只不过现在用户不是狂按back键返回,而是直接卸载.所以兵来将挡水来土掩,所以考虑各大门户,用第三方接口接入就能比较有效地留住用户了,现在就来讲讲如何接入第三方之微博篇. 按步骤来讲应该会比较清晰,那就一步一步来吧. 1.基于了解三方接口目的,先到官网下载SDK,微博是到微博的

ios学习-2015-7-8

ios开发:自定义UITableViewCell(类似微博那种cell).添加搜索栏(UITableViewCell进行搜索).增加 添加/删除按钮.UItableViewCell中进行排序

诗经 全文

诗经 全文 (带注释和译文) http://www.edu009.com/Article/HTML/Article_60756.html <诗经> 春秋·孔丘 <诗经>是我国第一部诗歌总集,先秦时代称为“诗”或“诗三百”,孔子加以了整理.汉武帝采纳董仲舒“罢黜百家,独尊儒术”的建议,尊“诗”为经典,定名为<诗经>. <诗经>现存诗歌 305 篇,包括西周初年到春秋中叶共 500 余年的民歌和朝庙乐章,分为风.雅.颂三章. “风”包括周南.召南.邶.鄘.卫.王

ios开发UI篇—使用纯代码自定义UItableviewcell实现一个简单的微博界面布局

本文转自 :http://www.cnblogs.com/wendingding/p/3761730.html ios开发UI篇—使用纯代码自定义UItableviewcell实现一个简单的微博界面布局 一.实现效果 二.使用纯代码自定义一个tableview的步骤 1.新建一个继承自UITableViewCell的类 2.重写initWithStyle:reuseIdentifier:方法 添加所有需要显示的子控件(不需要设置子控件的数据和frame,  子控件要添加到contentView中

iOS开发UI篇—以微博界面为例使用纯代码自定义cell程序编码全过程(一)

iOS开发UI篇-以微博界面为例使用纯代码自定义cell程序编码全过程(一) 一.storyboard的处理 直接让控制器继承uitableview controller,然后在storyboard中把继承自uiviewcontroller的控制器干掉,重新拖一个tableview controller,和主控制器进行连线. 项目结构和plist文件 二.程序逻辑业务的处理 第一步,把配图和plist中拿到项目中,加载plist数据(非png的图片放到spooding files中) 第二步,字

iOS开发项目篇—36封装微博业务

iOS开发项目篇—36封装微博业务 一.简单说明 1.请求参数面向模型 2.请求结果面向模型 3.对控制器来说应该屏蔽业务细节.不让控制器关心(知道)业务细节,它只需要知道自己在做某个业务 @通过一个专门的业务处理类:处理微博业务细节 说明: 业务:加载新的微博首页数据 实现:给新浪服务器发送一个GET请求 业务:加载更多的首页微博数据 实现1:给新浪服务器发送一个GET请求 实现2:去沙盒中加载以前离线缓存的微博数据  二.实现 1.新建一个微博业务处理类,继承自NSObject 微博业务处理

iOS开发项目篇—39获取用户未读的微博信息(信息提醒)

iOS开发项目篇—39获取用户未读的微博信息(信息提醒) 一.简单说明 1.实现效果       2.实现 (1)新建一个类,封装请求 查看新浪官方要求的请求参数 该类中的代码设计 YYUnreadCountParam.h文件 1 // YYUnreadCountParam.h 2 //封装请求参数的类 3 4 #import "YYBaseParam.h" 5 6 @interface YYUnreadCountParam : YYBaseParam 7 /**uid true in

iOS开发项目篇—31提示最新微博数

iOS开发项目篇—31提示最新微博数 一.简单说明 1.导入图片素材 2.关于提示条的位置分析 原本的显示情况: 说明:滚动tableView对它没有任何的影响,可以知道提示条的父控件不应该是tableView 加入提示条之后的情况:     解决方案: 说明: (1)导航条是导航控制器的view子控件,可以把提示条添加到导航控制器的view上,当刷新的时候,有view调整提示条的位置. (2)关于改变y的值以及transform的选择,如果是动画执行完成之后需要回复到以前的位置,那么建议使用t