iOS 新浪微博-5.1 首页微博列表_时间/配图
在上一篇中,我们已经把首页微博显示出来了,但还有很多细节,需要我们去调整的。这一章中,我们将处理好时间,配图,工具框及转发微博等小细节的功能。
时间处理
第一步:定义一个时间的类别,用于判断是昨天、今天等。
NSDate+Time.h
- #import <Foundation/Foundation.h>
- @interface NSDate (Time)
- /**
- * 判断某个时间是否为今年
- */
- - (BOOL)isThisYear;
- /**
- * 判断某个时间是否为昨天
- */
- - (BOOL)isYesterday;
- /**
- * 判断某个时间是否为今天
- */
- - (BOOL)isToday;
- @end
NSDate+Time.m
- //
- // NSDate+Time.m
- //
- // Created by jiangys on 15/10/25.
- // Copyright © 2015年 Jiangys. All rights reserved.
- //
- #import "NSDate+Time.h"
- @implementation NSDate (Time)
- /**
- * 判断某个时间是否为今年
- */
- - (BOOL)isThisYear
- {
- NSCalendar *calendar = [NSCalendar currentCalendar];
- // 获得某个时间的年月日时分秒
- NSDateComponents *dateCmps = [calendar components:NSCalendarUnitYear fromDate:self];
- NSDateComponents *nowCmps = [calendar components:NSCalendarUnitYear fromDate:[NSDate date]];
- return dateCmps.year == nowCmps.year;
- }
- /**
- * 判断某个时间是否为昨天
- */
- - (BOOL)isYesterday
- {
- NSDate *now = [NSDate date];
- // date == 2014-04-30 10:05:28 --> 2014-04-30 00:00:00
- // now == 2014-05-01 09:22:10 --> 2014-05-01 00:00:00
- NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
- fmt.dateFormat = @"yyyy-MM-dd";
- // 2014-04-30
- NSString *dateStr = [fmt stringFromDate:self];
- // 2014-10-18
- NSString *nowStr = [fmt stringFromDate:now];
- // 2014-10-30 00:00:00
- NSDate *date = [fmt dateFromString:dateStr];
- // 2014-10-18 00:00:00
- now = [fmt dateFromString:nowStr];
- NSCalendar *calendar = [NSCalendar currentCalendar];
- NSCalendarUnit unit = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay;
- NSDateComponents *cmps = [calendar components:unit fromDate:date toDate:now options:];
- return cmps.year == && cmps.month == && cmps.day == ;
- }
- /**
- * 判断某个时间是否为今天
- */
- - (BOOL)isToday
- {
- NSDate *now = [NSDate date];
- NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
- fmt.dateFormat = @"yyyy-MM-dd";
- NSString *dateStr = [fmt stringFromDate:self];
- NSString *nowStr = [fmt stringFromDate:now];
- return [dateStr isEqualToString:nowStr];
- }
- @end
第二步:在Status.m中重写时间的属性
- /**
- * 时间处理,重写
- 1.今年
- 1> 今天
- * 1分内: 刚刚
- * 1分~59分内:xx分钟前
- * 大于60分钟:xx小时前
- 2> 昨天
- * 昨天 xx:xx
- 3> 其他
- * xx-xx xx:xx
- 2.非今年
- 1> xxxx-xx-xx xx:xx
- */
- - (NSString *)created_at
- {
- NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
- // 如果是真机调试,转换这种欧美时间,需要设置locale
- fmt.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"];
- // 设置日期格式(声明字符串里面每个数字和单词的含义)
- // E:星期几
- // M:月份
- // d:几号(这个月的第几天)
- // H:24小时制的小时
- // m:分钟
- // s:秒
- // y:年
- fmt.dateFormat = @"EEE MMM dd HH:mm:ss Z yyyy";
- // _created_at = @"Tue Sep 30 17:06:25 +0600 2014";
- // 微博的创建日期
- NSDate *createDate = [fmt dateFromString:_created_at];
- // 当前时间
- NSDate *now = [NSDate date];
- // 日历对象(方便比较两个日期之间的差距)
- NSCalendar *calendar = [NSCalendar currentCalendar];
- // NSCalendarUnit枚举代表想获得哪些差值
- NSCalendarUnit unit = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
- // 计算两个日期之间的差值
- NSDateComponents *cmps = [calendar components:unit fromDate:createDate toDate:now options:];
- if ([createDate isThisYear]) { // 今年
- if ([createDate isYesterday]) { // 昨天
- fmt.dateFormat = @"昨天 HH:mm";
- return [fmt stringFromDate:createDate];
- } else if ([createDate isToday]) { // 今天
- if (cmps.hour >= ) {
- return [NSString stringWithFormat:@"%d小时前", (int)cmps.hour];
- } else if (cmps.minute >= ) {
- return [NSString stringWithFormat:@"%d分钟前", (int)cmps.minute];
- } else {
- return @"刚刚";
- }
- } else { // 今年的其他日子
- fmt.dateFormat = @"MM-dd HH:mm";
- return [fmt stringFromDate:createDate];
- }
- } else { // 非今年
- fmt.dateFormat = @"yyyy-MM-dd HH:mm";
- return [fmt stringFromDate:createDate];
- }
- }
这样,就可以显示出来了,但会有问题,就是不断的下拉刷新时,本来显示“刚刚”字样的,刷新后,可能变为“1分钟前”。由于“刚刚”的字体size不变化,因而显示“1分钟前”会导致显示不全。改进方法
- /** 时间 */
- // self.timeLabel.text = status.created_at;
- // self.timeLabel.frame = statusFrame.timeLabelF;
- /** 来源 */
- // self.sourceLabel.text = status.source;
- // self.sourceLabel.frame = statusFrame.sourceLabelF;
- /** 时间 */
- NSString *time = status.created_at;
- CGFloat timeX = statusFrame.nameLabelF.origin.x;
- CGFloat timeY = CGRectGetMaxY(statusFrame.nameLabelF) + StatusCellBorderW;
- CGSize timeSize = [time sizeWithFont:StatusCellTimeFont];
- self.timeLabel.frame = (CGRect){{timeX, timeY}, timeSize};
- self.timeLabel.text = time;
- /** 来源 */
- CGFloat sourceX = CGRectGetMaxX(self.timeLabel.frame) + StatusCellBorderW;
- CGFloat sourceY = timeY;
- CGSize sourceSize = [status.source sizeWithFont:StatusCellSourceFont];
- self.sourceLabel.frame = (CGRect){{sourceX, sourceY}, sourceSize};
- self.sourceLabel.text = status.source;
这样,每重新加载cell时,都重新计算一遍时间和来源的size。
效果:
配图
第一步:通过查看新浪微博的API,我们可以看到,返回的配图是一个集合。先定义好集合里的模型
Photo.h
- #import <Foundation/Foundation.h>
- @interface Photo : NSObject
- /** 缩略图地址 */
- @property (nonatomic, copy) NSString *thumbnail_pic;
- @end
第二步:在Status模型了,添加配图的集合属性,并指定,里面的集合是由Photo这个模型来构成的。
Status.h
- /** 微博配图地址。多图时返回多图链接。无配图返回“[]” */
- @property (nonatomic, strong) NSArray *pic_urls;
Status.m ,需要引用 #import "MJExtension.h"
- + (NSDictionary *)objectClassInArray
- {
- return @{@"pic_urls" : [Photo class]};
- }
第三步:拿到数据之后,接下来要做的事情
- 定义一个配图的View
- 定义一个装了该微博所有的配图View的容器
- 往容器里填充配图
- 计算这个容器的宽高
1.定义一个配图的View
StatusPhotoView.h
- #import <UIKit/UIKit.h>
- @class Photo;
- @interface StatusPhotoView : UIImageView
- /** 图片模型 */
- @property (nonatomic, strong) Photo *photo;
- @end
StatusPhotoView.m
- //
- // StatusPhotoView.m
- //
- // Created by jiangys on 15/10/25.
- // Copyright © 2015年 Jiangys. All rights reserved.
- //
- #import "StatusPhotoView.h"
- #import "Photo.h"
- #import "UIImageView+WebCache.h"
- @interface StatusPhotoView()
- @property (nonatomic, weak) UIImageView *gifView;
- @end
- @implementation StatusPhotoView
- - (UIImageView *)gifView
- {
- if (!_gifView) {
- UIImage *image = [UIImage imageNamed:@"timeline_image_gif"];
- UIImageView *gifView = [[UIImageView alloc] initWithImage:image];
- [self addSubview:gifView];
- self.gifView = gifView;
- }
- return _gifView;
- }
- - (instancetype)initWithFrame:(CGRect)frame
- {
- self = [super initWithFrame:frame];
- if (self) {
- // 内容模式
- self.contentMode = UIViewContentModeScaleAspectFill;
- // 超出边框的内容都剪掉
- self.clipsToBounds = YES;
- }
- return self;
- }
- - (void)setPhoto:(Photo *)photo
- {
- _photo = photo;
- // 设置图片
- [self sd_setImageWithURL:[NSURL URLWithString:photo.thumbnail_pic] placeholderImage:[UIImage imageNamed:@"timeline_image_placeholder"]];
- // 显示\隐藏gif控件
- // 判断是够以gif或者GIF结尾
- self.gifView.hidden = ![photo.thumbnail_pic.lowercaseString hasSuffix:@"gif"];
- }
- - (void)layoutSubviews
- {
- [super layoutSubviews];
- self.gifView.x = self.width - self.gifView.width;
- self.gifView.y = self.height - self.gifView.height;
- }
- @end
2.定义一个装了该微博所有的配图View的容器
StatusPhotosView.h
- #import <UIKit/UIKit.h>
- @interface StatusPhotosView : UIView
- /** 图片模型 */
- @property (nonatomic, strong) NSArray *photos;
- /**
- * 根据图片个数计算相册的尺寸
- */
- + (CGSize)sizeWithCount:(NSUInteger)count;
- @end
StatusPhotosView.m
- //
- // StatusPhotosView.m
- //
- // Created by jiangys on 15/10/25.
- // Copyright © 2015年 Jiangys. All rights reserved.
- //
- #import "StatusPhotosView.h"
- #import "StatusPhotoView.h"
- #import "Photo.h"
- #define StatusPhotoWH 70
- #define StatusPhotoMargin 10
- #define StatusPhotoMaxCol(count) ((count==4)?2:3)
- @implementation StatusPhotosView
- - (void)setPhotos:(NSArray *)photos
- {
- _photos = photos;
- NSUInteger photosCount = photos.count;
- // 创建足够多的图片控制
- while (self.subviews.count < photosCount) {
- StatusPhotoView *photoView = [[StatusPhotoView alloc] init];
- [self addSubview:photoView];
- }
- // 遍历所有的图片控件,设置图片
- for (int i = ; i < self.subviews.count; i++) {
- StatusPhotoView *photoView = self.subviews[i];
- if (i < photosCount) {
- photoView.photo = photos[i];
- photoView.hidden = NO;
- } else{
- photoView.hidden=YES;
- }
- }
- }
- - (void)layoutSubviews
- {
- [super layoutSubviews];
- // 设置图片的尺寸和位置
- NSUInteger photosCount = self.photos.count;
- int maxCol = StatusPhotoMaxCol(photosCount);
- for (int i = ; i<photosCount; i++) {
- StatusPhotoView *photoView = self.subviews[i];
- int col = i % maxCol;
- photoView.x = col * (StatusPhotoWH + StatusPhotoMargin);
- int row = i / maxCol;
- photoView.y = row * (StatusPhotoWH + StatusPhotoMargin);
- photoView.width = StatusPhotoWH;
- photoView.height = StatusPhotoWH;
- }
- }
- + (CGSize)sizeWithCount:(NSUInteger)count
- {
- // 最大列数(一行最多有多少列)
- int maxCols = StatusPhotoMaxCol(count);
- NSUInteger cols = (count >= maxCols)? maxCols : count;
- CGFloat photosW = cols * StatusPhotoWH + (cols - ) * StatusPhotoMargin;
- // 行数
- NSUInteger rows = (count + maxCols - ) / maxCols;
- CGFloat photosH = rows * StatusPhotoWH + (rows - ) * StatusPhotoMargin;
- return CGSizeMake(photosW, photosH);
- }
- @end
3.StatusFrame.m里计算配图的宽高
- /** 配图 */
- CGFloat originalH = ;
- if (status.pic_urls.count) { // 有配图
- CGFloat photosX = contentX;
- CGFloat photosY = CGRectGetMaxY(self.contentLabelF) + StatusCellBorderW;
- CGSize photosSize = [StatusPhotosView sizeWithCount:status.pic_urls.count];
- _photosViewF = (CGRect){{photosX, photosY}, photosSize};
- originalH = CGRectGetMaxY(self.photosViewF) + StatusCellBorderW;
- } else { // 没配图
- originalH = CGRectGetMaxY(self.contentLabelF) + StatusCellBorderW;
- }
4.在StatusCell.m里创建定义容器,初始化容器并赋值
- /** 配图 */
- @property (nonatomic, weak) StatusPhotosView *photosView;
初始化容器initWithStyle
- /** 配图 */
- StatusPhotosView *photosView = [[StatusPhotosView alloc] init];
- [originalView addSubview:photosView];
- self.photosView = photosView;
赋值setStatusFrame
- /** 配图 */
- if (status.pic_urls.count) {
- self.photosView.frame = statusFrame.photosViewF;
- self.photosView.photos = status.pic_urls;
- self.photosView.hidden = NO;
- } else {
- self.photosView.hidden = YES;
- }
效果如下图:
iOS 新浪微博-5.1 首页微博列表_时间/配图的更多相关文章
- iOS 新浪微博-5.2 首页微博列表_转发微博/工具栏
继续于上一篇,还是做首页的功能,这一篇把剩下的首页继续完善. 看看上面的图片,分析: 1.转发微博里面的内容,和原创微博是一样的,由文字+配图组成.这应该放在一个UIView里处理. 2.工具栏也当成 ...
- iOS 新浪微博-5.3 首页微博列表_集成图片浏览器
实际上,我们可以使用李明杰在教程里集成的MJPhotoBrowser,地址: http://code4app.com/ios/快速集成图片浏览器/525e06116803fa7b0a000001 使用 ...
- iOS 新浪微博-5.0 首页微博列表
首页显示微博列表,是微博的核心部分,这一章节,我们主要是显示出微博的列表. 导入第三方类库 pod 'SDWebImage', '~> 3.7.3' pod 'MJRefresh', '~> ...
- IOS SWIFT UITableView 实现简单微博列表
// // Weibo.swift // UITableViewCellExample // // Created by XUYAN on 15/8/15. // Copyright (c) 2015 ...
- Day8-微信小程序实战-交友小程序-首页用户列表渲染及多账号调试及其点赞功能的实现
在这之前已经把编辑个人的所有信息的功能已经完成了 之后先对首页的列表搞动态的,之前都是写死的静态 1.之前都是把好友写死的,现在就在js里面定义一个数组,用循环来动态的绑定 在onReady中定义,取 ...
- 【Android 我的博客APP】1.抓取博客首页文章列表内容——网页数据抓取
打算做个自己在博客园的博客APP,首先要能访问首页获取数据获取首页的文章列表,第一步抓取博客首页文章列表内容的功能已实现,在小米2S上的效果图如下: 思路是:通过编写的工具类访问网页,获取页面源代码, ...
- PHPCMS v9 实现首页,列表页,内容页调用点击量方法
大家好,今天有点闲,看很多朋友经常问PHPCMS v9 首页,列表页,内容页调用点击怎么弄,打算抽时间把代码全部归纳出来,以便大家日后使用,如下: 1,首页调用点击量 {pc:content acti ...
- 织梦首页、列表页调用文章body内容的两种方法
http://blog.csdn.net/langyu1021/article/details/52261411 关于首页.列表页调用文章body内容的两种方法,具体方法如下: 第一种方法: {ded ...
- iOS 新浪微博-1.1框架升级
在iOS 新浪微博-1.0框架搭建 中,使用的是xcode5.1.1开发.现在把重整了一下框架 改为xcode7.0开发 使用cocoaPad管理第三方库 程序将托管到github上 在改为xcode ...
随机推荐
- hdu3613 Best Reward【Manacher】
Best Reward Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total ...
- hdu3374 String Problem【最小表示法】【exKMP】
String Problem Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
- okvis论文解读
C. Keypoint Matching and Keyframe Selection 我们的处理流程采用定制的多尺度SSE优化Harris角点检测器与BRISK描述符提取相结合[12].检测器通过逐 ...
- ubuntu 搜狗输入法 在中断失效
实测是更换了皮肤后,出现在中断输入故障,乱码.在其他界面可能是正常的,更换语言没用. killall fcitx输入法突然好了(根据网友所说,更改一堆东西貌似并没有什么用) 此时关闭输入法皮肤一切正常 ...
- FFmpeg制作+x264+faac
https://blog.csdn.net/leixiaohua1020/article/details/47071547 雷神的博客 https://www.jianshu.com/p/3f023 ...
- android gradle jnilibs
https://blog.csdn.net/xx326664162/article/details/51167849 [ABIXCPU] Android jniLibs下目录详解(.so文件) htt ...
- AndroidStudio_RecyclerView
在这里回顾一下RecyclerView的用法 RecyclerView的用法与Button的用法很类似,只是要增加一个Adapter.java文件和item.xml文件 具体用法: 1.在page1. ...
- Javascript面向对象编程(三):非构造函数的继承(对象的深拷贝与浅拷贝)
Javascript面向对象编程(三):非构造函数的继承 作者: 阮一峰 日期: 2010年5月24日 这个系列的第一部分介绍了"封装",第二部分介绍了使用构造函数实现&quo ...
- nodejs 学习一 process.execPath 、 __dirname、process.cwd()的区别
process.execPath node.exe的绝对路径 __dirname 当前执行到__dirname文件文件路径 process.cwd() 启动node命令的目录的绝对路劲
- 对web标准化(或网站重构)知道哪些相关的知识,简述几条你知道的Web标准?
网页主要有三部分组成:结构(Structrue).表现(Presentation)和行为(Behavior).对应的网站标准也分为三方面: 1.结构化标准语言,主要包括XHTML和XML: 2.表现标 ...