学习HM微博项目第7天
步骤:首页14-时间 -> 首页15-来源 -> 首页16-配图相册 -> 首页17-头像
首页14-时间
APP的界面.png通过新浪官方的APP可知,在微博发送时间上是这么分类的:
/**
1.今年
1> 今天
* 1分内: 刚刚
* 1分~59分内:xx分钟前
* 大于60分钟:xx小时前
2> 昨天
* 昨天 xx:xx
3> 其他
* xx-xx xx:xx
2.非今年
1> xxxx-xx-xx xx:xx
*/
参考官方的APP后,在HMStatus模型中重写created_at的getter方法,判断时间并返回所定义的时间格式。具体代码如下:
/**
* 重写get方法
*/
- (NSString *)created_at
{
NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
//如果是真机调试,转换欧美时间,需要设置locale
fmt.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"];
//设置日期格式(声明字符串里面每个数字和单词的含义) @"Tue Sep 30 17:06:25 +0800 2014";
fmt.dateFormat = @"EEE MMM dd HH:mm:ss Z yyyy";
//微博的创建时间
NSDate *createDate = [fmt dateFromString:_created_at];
//当前时间
NSDate *now = [NSDate date];
//日历对象(方便比较两个日期之间的差距)
NSCalendar *calendar = [NSCalendar currentCalendar];
//NSCalendarUnit枚举代表想获得哪些差值
NSCalendarUnit unit =NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
//计算2个日期之间的差值
NSDateComponents *cmps = [calendar components:unit fromDate:createDate toDate:now options:0];
//判断时间
if ([createDate isThisYear]) {//今年
if ([createDate isYesterday]) {//昨天
fmt.dateFormat = @"昨天 HH:mm";
return [fmt stringFromDate:createDate];
}else if ([createDate isToday]){
if (cmps.hour > 1) {//大于1小时
return [NSString stringWithFormat:@"%ld小时前",cmps.hour];
}else if (cmps.minute > 1){//大于1分钟
return [NSString stringWithFormat:@"%ld分钟前",cmps.minute];
}else{//1分钟内
return @"刚刚";
}
}else{//今年的其他日子
fmt.dateFormat = @"MM-dd HH:mm";
return [fmt stringFromDate:createDate];
}
}else{//非今年
fmt.dateFormat = @"yyyy-MM-dd HH:mm";
return [fmt stringFromDate:createDate];
}
}
注意:其中,时间的具体判断方法封装在NSDate的Category(NSDate+Extension)中,如下:
isThisYear isYesterday isToday首页15-来源
从前文可知,除了时间需要重新定义格式,来源也需要重新定义格式(原本是一个href链接)。
一旦来源确定后,之后不会多次调用,所以这里只需要对HMStatus模型的Source重写setter方法即可。如下:
- (void)setSource:(NSString *)source
{
// 范例 <a href="http://weibo.com/" rel="nofollow">微博 weibo.com</a>
//截取字符串
//如果出现警告:reason: '-[__NSCFConstantString substringWithRange:]: Range {9223372036854775808, 18446744073709551615} out of bounds; string lenght 0,
//原因:猜测是api的限制导致的
//做法:先判断source的length
if (source.length != 0) {
NSRange range = NSMakeRange(0, 0);
range.location = [source rangeOfString:@">"].location + 1;
// range.length = [source rangeOfString:@"</"].location - range.location;
range.length = [source rangeOfString:@"<" options:NSBackwardsSearch].location - range.location;
_source = [NSString stringWithFormat:@"来自%@",[source substringWithRange:range]];
}
}
注意:按照前文的所定义的时间格式,每条微博都随着时间而改变,created_at的getter方法会多次调用,时间所占用的frame也会随着改变,时间的frame的改变会影响来源的frame。所以在自定义cell的类HMStatusCell的setStatusFrame:方法中,要完善时间与来源的有关代码,如下:
setStatusFrame:方法APP的界面:
APP的界面.png首页16-配图相册
APP操作演示:
APP操作演示从APP的操作演示中可知,原创微博或转发微博的配图数量不定,可能有1-9张等多种情况。
前文中,在自定义cell的类HMStatusCell的setStatusFrame:方法中,配图所在位置只是一个UIImageView,只能存放一张图片。现在,要新建一个继承自UIView的HMStatusPhotosView类,作为配图相册,存放1-9张图片。
HMStatusPhotosView类只需要把属性photos和计算整个配图相册的尺寸方法提供给外界使用,而如何设置配图相册里的图片及其frame、计算整个配图相册的尺寸都封装该类里。封装的具体代码如下:
至于外界,只需要通过以下的代码就可以轻松使用上面所封装的代码,从而设置配图相册。
在HMStatusCell的setStatusFrame:方法中,设置配图,如下:
HMStatusCell的setStatusFrame:方法在HMStatusFrame的setStatus:方法设置整个配图相册的frame,如下:
HMStatusFrame的setStatus:方法如果仔细观察APP操作演示里的配图,可以发现有些图片在图片的右下角会显示gif表明是gif格式。
实际上,在上文设置图片相册里的图片的封装代码中,新建了一个名为HMStatusPhotoView类来存放每一张单独的图片,而gif图片控件的显示或隐藏就交给HMStatusPhotoView类自己判断,不需要让外界知道。
HMStatusPhotoView.m的具体代码如下:
首页17-头像
APP的界面:
APP的界面从新浪官方微博可知,有些头像的右下角会有特别的认证标志。
在HMUser模型中,声明新的属性-认证类型。
如下:
认证类型通过枚举来区分,如下:
认证类型的枚举新建一个继承自UIImageView的HMIconView来显示认证类型标志。
HMIconView类的两个关键方法如下:
总结:时间和来源要注意区分getter和setter方法的使用。配图相册要活用hidden属性控制图片控件的显示或隐藏。另外一定要把子控件的frame计算放在layoutSubviews方法中。