步骤:首页08-显示微博未读数 -> 首页09-自定义cell -> 首页10-计算cell子控件frame -> 首页11-计算配图的frame -> 首页12-计算转发的frame -> 首页13-工具条
在viewDidLoad方法中,通过设置定时器,每隔一定时间获得微博未读数,并在tabBar上的tabBarItem上显示出来。注意,要处理好UI刷新与数据的关系,保证在UI刷新的同时,从服务器所获得的数据能及时显示出来,如下:
//获得未读数(时间间隔为60s)
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:60 target:self selector:@selector(setupUnreadCount) userInfo:nil repeats:YES];
//主线程也会抽时间处理一下timer(不管主线程是否正在处理其他事件)
[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
如何从服务器获得微博未读数可见setupUnreadCount:方法,如下:
/**
* 获得微博未读数
*/
- (void)setupUnreadCount
{
// HMLog(@"setupUnreadCound");
// return;
// 1.请求管理者
AFHTTPRequestOperationManager *mgr = [AFHTTPRequestOperationManager manager];
// 2.拼接请求参数
HMAccount *account = [HMAccountTool account];
NSMutableDictionary *params = [NSMutableDictionary dictionary];
params[@"access_token"] = account.access_token;
params[@"uid"] = account.uid;
// 3.发送请求
[mgr GET:@"https://rm.api.weibo.com/2/remind/unread_count.json" parameters:params success:^(AFHTTPRequestOperation *operation, NSDictionary *responseObject) {
// HMLog(@"请求成功-%@", responseObject);
//微博的未读数
// int status = [responseObject[@"status"] intValue];
//设置提醒数字
// self.tabBarItem.badgeValue = [NSString stringWithFormat:@"%d",status];
//description: @10 --> @"10"
//设置提醒数字(微博的未读数)
NSString *status = [responseObject[@"status"] description];
//在ios8中,设置应用的application badge value需要得到用户的许可
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
if ([status isEqualToString:@"0"]) {//如果是0清空
self.tabBarItem.badgeValue = nil;
[UIApplication sharedApplication].applicationIconBadgeNumber = 0;
}else{//非0情况
self.tabBarItem.badgeValue = status;
[UIApplication sharedApplication].applicationIconBadgeNumber = status.intValue;
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
HMLog(@"请求失败-%@", error);
}];
}
说明:
1.每一次微博数据刷新成功后,要清空图标的数字,如下:
2.在setupUnreadCount:方法中,除了tabBar上的tabBarItem会显示微博未读数,APP图标上也要显示微博未读数。但是当APP进入后台后,APP会进入后台暂停状态。要使APP后台保持运行状态,必须做些设置。
在AppDelegate的applicationDidEnterBackground:方法,设置后台能长时间运行,如下:
APP的界面:
前文中的tableViewCell是系统自带的,为了让cell能够显示更多的内容并且按照我们的要求来显示,我们需要自定义cell。自定义cell的步骤较为复杂,需要分几步走。自定义cell的步骤可见”iOS总结“。
自定义cell的步骤:
1.创建一个继承自UITableViewCell的HMStatusCell
2.在HMStatusCell.m的initWithStyle:方法中进行子控件的初始化:
1> 将有可能显示的所有子控件都添加到contentView中
2> 顺便设置子控件的一些属性(一次性的设置:字体、⽂字颜色、背景)
3.提供2个模型
1> 一个是数据模型(⽂字数据 + 图片数据) HMStatus
2> 一个是frame模型(数据模型 + 所有子控件的frame + cell的⾼高度) HMStatusFrame
4.cell应该提供⼀个frame模型属性(setStatusFrame:方法)
1> 将frame模型传递给cell
2> cell根据frame模型给子控件设置frame,根据数据模型给⼦控件设置数据
3> cell根据数据模型决定显示和隐藏哪些⼦子控件
5.在tableView的代理方法返回cell的⾼度
在HMStatusFrame模型中,要包含3个信息:
1.一个数据模型HMStatus
2.一个cell内部所有子控件的frame信息,在HMStatus模型中的set方法中设置
3.一个cell的高度,同样在HMStatus模型中的set方法中设置
setStatus:方法的具体代码:
- (void)setStatus:(HMStatus *)status
{
_status = status;
//注意:“取出”用户模型
HMUser *user = status.user;
//计算子控件的frame
CGFloat cellW = [UIScreen mainScreen].bounds.size.width;
/* 原创微博 */
/** 头像 */
CGFloat iconWH = 35;
CGFloat iconX = HMStatusCellBorderW;
CGFloat iconY = HMStatusCellBorderW;
self.iconViewF = CGRectMake(iconX, iconY, iconWH, iconWH);
/** 昵称 注意:要显示需要在cell设置font*/
CGFloat nameX = CGRectGetMaxX(self.iconViewF) + HMStatusCellBorderW;
CGFloat nameY = iconY;
CGSize nameSize = [self sizeWithText:user.name font:HMStatusCellNameLableFont];
self.nameLabelF = (CGRect){{nameX, nameY},nameSize};
/** 会员图标 */
if (user.vip) {
CGFloat vipX = CGRectGetMaxX(self.nameLabelF) + HMStatusCellBorderW;
CGFloat vipY = nameY;
CGFloat vipH = nameSize.height;
CGFloat vipW = 14;
self.vipViewF = CGRectMake(vipX, vipY, vipW, vipH);
}
/** 时间 */
CGFloat timeX = nameX;
CGFloat timeY = CGRectGetMaxY(self.nameLabelF) + HMStatusCellBorderW;
CGSize timeSize = [self sizeWithText:status.created_at font:HMStatusCellTimeLableFont];
self.timeLabelF = (CGRect){{timeX, timeY},timeSize};
/** 来源 */
CGFloat sourceX = CGRectGetMaxX(self.timeLabelF) + HMStatusCellBorderW;
CGFloat sourceY = timeY;
CGSize sourceSize = [self sizeWithText:status.source font:HMStatusCellSourceLableFont];
self.sourceLabelF = (CGRect){{sourceX, sourceY},sourceSize};
/** 正文 */
CGFloat contentX = iconX;
CGFloat contentY = MAX(CGRectGetMaxY(self.iconViewF), CGRectGetMaxY(self.timeLabelF)) + HMStatusCellBorderW;
CGFloat maxW = cellW - 2 * HMStatusCellBorderW;
CGSize contentSize = [self sizeWithText:status.text font:HMStatusCellContentLableFont maxW:maxW];
self.contentLabelF = (CGRect){{contentX, contentY},contentSize};
/** 配图 */
/** 原创微博整体 */
CGFloat originalX = 0;
CGFloat originalY = 0;
CGFloat originalH = CGRectGetMaxY(self.contentLabelF) + HMStatusCellBorderW;
CGFloat originalW = cellW ;
self.originalViewF = CGRectMake(originalX, originalY, originalW, originalH);
/** cell的高度 */
self.cellHeight = CGRectGetMaxY(self.originalViewF);
}
其中,size的计算方法如下:
注意:为了确保HMStatus模型能够存放从服务器得到的数据,要保证属性名称与服务器的保持一致。
在前文的基础上,继续完善自定义cell,在HMStatusCell类中添加子控件,根据HMStatus模型和HMStatusFrame模型分别给cell设置数据和frame。
注意:要将所有子控件的frame计算都放在HMStatusFrame模型中。而HMStatus模型存放的是我们从服务器所获得的信息。
在HMStatusCell的initWithStyle:方法中初始化工具条,如下:
该工具条HMStatusToolBar继承自UIView,在initWithFrame:方法初始化所有子控件,但是要在layoutSubViews方法中设置子控件的位置和尺寸。另外,该工具条还要有一个HMStatus模型,用来获取转发、评论等信息,显示在工具条的按钮上。
APP的界面:
这一天主要是自定义cell,在HMStatusCell类中添加子控件,并根据HMStatus模型和HMStatusFrame模型分别给cell设置数据和frame。
注意:
1.在HMStatus模型存放从服务器所获得的信息
2.在HMStatusFrame模型中计算所有子控件的frame