首页 > 代码库 > iOS开发项目篇—39获取用户未读的微博信息(信息提醒)

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    int64    需要获取消息未读数的用户UID,必须是当前登录用户。*/ 8 @property(nonatomic,copy)NSString *uid; 9 10 @end

YYUnreadCountParam.m文件不做额外的处理

(2)新建一个类,用来封装获取的返回数据

该类中的代码设计

YYUnreadCountResult.h文件

 1 // 2 //  YYUnreadCountResult.h 3 // 封装请求成功返回结果数据的类 4  5 #import <Foundation/Foundation.h> 6  7 @interface YYUnreadCountResult : NSObject 8 /**status    int    新微博未读数*/ 9 @property(nonatomic,assign)int status;10 11 /**follower    int    新粉丝数*/12 @property(nonatomic,assign)int follower;13 14 /**cmt    int    新评论数*/15 @property(nonatomic,assign)int cmt;16 17 /**dm    int    新私信数*/18 @property(nonatomic,assign)int dm;19 20 /**mention_status    int    新提及我的微博数*/21 @property(nonatomic,assign)int dmention_status;22 23 /**mention_cmt    int    新提及我的评论数*/24 @property(nonatomic,assign)int mention_cmt;25 26 /**消息未读数=新私信数+新评论数+新提及我的微博数+新提及我的评论数*/27 -(int)messageCount;28 29 /**所有未读数=新微博未读数+新粉丝数+新私信数+新评论数+新提及我的微博数+新提及我的评论数*/30 -(int)totalCount;31 @end

YYUnreadCountResult.m文件

 1 // 2 //  YYUnreadCountResult.m 3 // 4  5 #import "YYUnreadCountResult.h" 6  7 @implementation YYUnreadCountResult 8 -(int)messageCount 9 {10     return self.cmt+self.dm+self.mention_cmt+self.dmention_status;11 }12 13 -(int)totalCount14 {15     return  self.messageCount + self.status + self.follower;16 }17 @end

(3)封装业务处理类

 YYUserTool.h文件

 1 // 2 //  YYUserTool.h 3 // 4  5 #import <Foundation/Foundation.h> 6 #import "YYUserInfoParam.h" 7 #import "YYUserInfoResult.h" 8 #import "YYBaseTool.h" 9 #import "YYUnreadCountParam.h"10 #import "YYUnreadCountResult.h"11 12 @interface YYUserTool : YYBaseTool13 /**14  *  加载用户的个人信息15  *16  *  @param param   请求参数17  *  @param success 请求成功后的回调(请将请求成功后想做的事情写到这个block中)18  *  @param failure 请求失败后的回调(请将请求失败后想做的事情写到这个block中)19  */20 +(void)userInfoWithParam:(YYUserInfoParam *)param success:(void (^)(YYUserInfoResult *result))success failure:(void (^)(NSError *error))failure;21 22 /**23  *  加载未读的微博信息24  *25  *  @param param   请求参数26  *  @param success 请求成功后的回调(请将请求成功后想做的事情写到这个block中)27  *  @param failure 请求失败后的回调(请将请求失败后想做的事情写到这个block中)28  */29 +(void)unreadCountWithParam:(YYUnreadCountParam *)param success:(void (^)(YYUnreadCountResult *result))success failure:(void (^)(NSError *error))failure;30 @end

 YYUserTool.m文件

 1 // 2 //  YYUserTool.m 3 // 4  5 #import "YYUserTool.h" 6 #import "YYHttpTool.h" 7 #import "MJExtension.h" 8 #import "YYUnreadCountResult.h" 9 10 11 @implementation YYUserTool12 +(void)userInfoWithParam:(YYUserInfoParam *)param success:(void (^)(YYUserInfoResult *result))success failure:(void (^)(NSError *error))failure13 {14     15     [self getWithUrl:@"https://api.weibo.com/2/users/show.json" param:param resultClass:[YYUserInfoResult class] success:success failure:failure];16 }17 18 +(void)unreadCountWithParam:(YYUnreadCountParam *)param success:(void (^)(YYUnreadCountResult *))success failure:(void (^)(NSError *))failure19 {20     [self getWithUrl:@"https://rm.api.weibo.com/2/remind/unread_count.json" param:param resultClass:[YYUnreadCountResult class] success:success failure:failure];21 }22 @end

 

二、细节处理

1.系统挂起

新的问题:一进入后台,定时器就停止,不再会发送请求,获取最新的未读数据。

如何解决?在程序进入到后台的那一刻,告诉系统,保持运行状态。

补充

运行状态

停止状态(关闭·程序退出)

挂起状态(进入待后台·暂停)

因为手机的内存是及其有限的,因此它不可能随随便便让所有的程序进入到后台后都还处于运行状态。因此,如果程序进入后台,还想让其保持运行状态的话,需要程序进入到后台那一刻的时候进行申请。

提示:默认情况下,所有程序进入到后台,都将处于挂起状态(暂停)。

可以提醒操作系统,当前这个应用需要在后台开启一个线程执行任务,如果这样的话操作系统会允许程序在后台仍然保持运行状态(能够持续的时间是不确定的,随时可能会被杀掉)

说明:存在于内存中的程序可能是下面三种情况

(1)前台运行

(2)后台运行

(3)休眠(挂起,暂停)

当系统发生内存警告的时候,处于休眠状态的程序将最可能被杀死,因为它此时什么都没做,却还占据着内存空间。

发生内存警告时的优先级保证:(1)>(2)>(3)

如何让程序在系统中长时间存活?需要设置配置文件。

以欺骗的方式,告诉系统这个应用是播放音频的,不要关闭。可以在代理中,设置一个0kb的文件让其循环播放,以试图骗过系统。

使用上述业务类的代码设计:

YYTabBarViewController.m文件

  1 //  2 //  YYTabBarViewController.m  3 //  4   5 #import "YYTabBarViewController.h"  6 #import "YYHomeTableViewController.h"  7 #import "YYDiscoverViewController.h"  8 #import "YYMessageViewController.h"  9 #import "YYProfileViewController.h" 10 #import "UIImage+Extension.h" 11 #import "YYNavigationViewController.h" 12 #import "YYTabBar.h" 13 #import "YYComposeViewController.h" 14 #import "YYUnreadCountResult.h" 15 #import "YYUnreadCountParam.h" 16 #import "YYUserTool.h" 17 #import "YYAccountTool.h" 18 @interface YYTabBarViewController ()<UITabBarControllerDelegate,YYTabBarDelegate> 19 @property(nonatomic,weak)YYHomeTableViewController *home; 20 @property(nonatomic,weak)YYMessageViewController *message; 21 @property(nonatomic,weak)YYProfileViewController *profile; 22 @end 23  24 @implementation YYTabBarViewController 25  26  27 - (void)viewDidLoad 28 { 29     [super viewDidLoad]; 30     //添加四个子控制器 31     [self addAllChildVcs]; 32  33     // 调整tabbar 34     [self addCustomTabBar]; 35      36     //设置定时器,每隔两秒就获取一次未读微博信息 37     [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(getUnreadCount) userInfo:nil repeats:YES]; 38 } 39  40 -(void)getUnreadCount 41 { 42     //1.请求参数 43     YYUnreadCountParam *param=[YYUnreadCountParam param]; 44     param.uid=[YYAccountTool accountModel].uid; 45      46      47     //2.获取未读微博信息 48     [YYUserTool unreadCountWithParam:param success:^(YYUnreadCountResult *result) { 49         //显示新的微博数 50         if (result.status==0) { 51             self.home.tabBarItem.badgeValue=http://www.mamicode.com/nil; 52         }else 53         { 54             self.home.tabBarItem.badgeValue=http://www.mamicode.com/[NSString stringWithFormat:@"%d",result.status]; 55         } 56          57         //显示消息未读数 58         if (result.messageCount==0) { 59             self.message.tabBarItem.badgeValue=http://www.mamicode.com/nil; 60         }else 61         { 62             self.message.tabBarItem.badgeValue=http://www.mamicode.com/[NSString stringWithFormat:@"%d",result.messageCount]; 63         } 64          65         //显示新的粉丝数量 66         if (result.follower==0) { 67             self.profile.tabBarItem.badgeValue=http://www.mamicode.com/nil; 68         }else 69         { 70             self.profile.tabBarItem.badgeValue=http://www.mamicode.com/[NSString stringWithFormat:@"%d",result.follower]; 71         } 72          73         //在图标上显示所有的未读数 74         [UIApplication sharedApplication].applicationIconBadgeNumber=result.totalCount; 75     } failure:^(NSError *error) { 76         YYLog(@"请求失败"); 77     }]; 78   79 } 80 -(void)addAllChildVcs 81 { 82     YYHomeTableViewController *home=[[YYHomeTableViewController alloc]init]; 83     [self addOneChildVc:home title:@"首页" imageName:@"tabbar_home" selectedImageName:@"tabbar_home_selected"]; 84     self.home=home; 85      86     YYMessageViewController *message=[[YYMessageViewController alloc]init]; 87     [self addOneChildVc:message title:@"消息" imageName:@"tabbar_message_center" selectedImageName:@"tabbar_message_center_selected"]; 88     self.message=message; 89      90     YYDiscoverViewController *discover=[[YYDiscoverViewController alloc]init]; 91     [self addOneChildVc:discover title:@"发现" imageName:@"tabbar_discover" selectedImageName:@"tabbar_discover_selected"]; 92      93     YYProfileViewController *profile=[[YYProfileViewController alloc]init]; 94     [self addOneChildVc:profile title:@"" imageName:@"tabbar_profile" selectedImageName:@"tabbar_profile_selected"]; 95     self.profile=profile; 96 } 97  98 -(void)addCustomTabBar 99 {100     YYTabBar *customTabBar = [[YYTabBar alloc] init];101     //设置代理102     customTabBar.delegate=self;103     // 更换系统自带的tabbar104     [self setValue:customTabBar forKeyPath:@"tabBar"];105 }106 107 108 #pragma mark-YYTabBarDelegate109 -(void)tabBarDidClickedPlusButton:(YYTabBar *)tabBar110 {111     //弹出发微博的控制器112     YYComposeViewController *compose=[[YYComposeViewController alloc]init];113     YYNavigationViewController *nav=[[YYNavigationViewController alloc]initWithRootViewController:compose];114     [self presentViewController:nav animated:YES completion:nil];115 }116 117 118 /**119  *  添加一个子控制器120  *121  *  @param childVC           子控制对象122  *  @param title             标题123  *  @param imageName         图标124  *  @param selectedImageName 选中时的图标125  */126 -(void)addOneChildVc:(UIViewController *)childVc title:(NSString *)title imageName:(NSString *)imageName selectedImageName:(NSString *)selectedImageName127 {128     //随机设置子控制器的背景颜色129 //    childVc.view.backgroundColor=YYRandomColor;130     131     //设置标题132     childVc.title=title;  //相当于设置了后两者的标题133 134     135     //设置图标136     childVc.tabBarItem.image=[UIImage imageWithName:imageName];137     //设置选中时的图标138     UIImage *selectedImage=[UIImage imageWithName:selectedImageName];139     140     //设置tabBarItem普通状态下文字的颜色141     NSMutableDictionary *textAttrs=[NSMutableDictionary dictionary];142     textAttrs[UITextAttributeTextColor]=[UIColor blackColor];143     textAttrs[UITextAttributeFont]=[UIFont systemFontOfSize:10];144     [childVc.tabBarItem setTitleTextAttributes:textAttrs forState:UIControlStateNormal];145     146     //设置tabBarItem普通状态下文字的颜色147     NSMutableDictionary *selectedtextAttrs=[NSMutableDictionary dictionary];148     selectedtextAttrs[UITextAttributeTextColor]=[UIColor orangeColor];149     [childVc.tabBarItem setTitleTextAttributes:selectedtextAttrs forState:UIControlStateSelected];150     151     if (iOS7) {152         // 声明这张图片用原图(别渲染)153         selectedImage = [selectedImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];154     }155     childVc.tabBarItem.selectedImage = selectedImage;156     157      // 添加为tabbar控制器的子控制器158     YYNavigationViewController *nav=[[YYNavigationViewController alloc]initWithRootViewController:childVc];159     160     [self addChildViewController:nav];161 162 }163 164 @end

程序的后台处理代码:

 YYAppDelegate.m文件

  1 //  2 //  YYAppDelegate.m  3 //  4   5 #import "YYAppDelegate.h"  6 #import "YYOAuthViewController.h"  7 #import "YYControllerTool.h"  8 #import "YYAccountTool.h"  9 #import "YYAccountModel.h" 10 #import "SDWebImageManager.h" 11 #import "SDImageCache.h" 12 #import "AFNetworking.h" 13 #import "MBProgressHUD+MJ.h" 14  15 #import <AVFoundation/AVFoundation.h> 16  17 @implementation YYAppDelegate 18  19 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 20 { 21     //欺骗 22 //    AVAudioPlayer *player=[[AVAudioPlayer alloc]initWithContentsOfURL:@"xxx" error:nil]; 23 //    player.numberOfLoops=-1;//循环播放 24 //    [player prepareToPlay];//缓冲 25 //    [player play];//播放 26      27      28    //1.创建窗口 29     self.window=[[UIWindow alloc]init]; 30     self.window.frame=[UIScreen mainScreen].bounds; 31      32      33     //2.显示窗口(主窗口) 34     [self.window makeKeyAndVisible]; 35      36     //3.设置窗口的根控制器 37     YYAccountModel *account=[YYAccountTool accountModel]; 38      39     if (account) {  //  存在成功授权的账号信息 40         [YYControllerTool chooseRootViewController]; 41     }else  //没有登陆过 42     { 43         self.window.rootViewController=[[YYOAuthViewController alloc]init]; 44     } 45      46     //4.监控网络状态 47     AFNetworkReachabilityManager *mgr=[AFNetworkReachabilityManager sharedManager]; 48     //当网络状态改变的时候,就会调用 49     [mgr setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) { 50         switch (status) { 51             case AFNetworkReachabilityStatusUnknown://未知网络 52             case AFNetworkReachabilityStatusNotReachable://没有网络 53                 YYLog(@"没有网络(断网)"); 54                 [MBProgressHUD showError:@"网络异常,请检查网络设置!"]; 55                 break; 56             case AFNetworkReachabilityStatusReachableViaWWAN://手机自带网络 57                 YYLog(@"手机自带网络"); 58                 break; 59             case AFNetworkReachabilityStatusReachableViaWiFi://WIFI 60                 YYLog(@"WIFI"); 61                 break; 62         } 63     }]; 64     //开始监控 65     [mgr startMonitoring]; 66     return YES; 67 } 68  69  70 - (void)applicationDidReceiveMemoryWarning:(UIApplication *)application 71 { 72     // 赶紧清除所有的内存缓存 73     [[SDImageCache sharedImageCache] clearMemory]; 74      75     // 赶紧停止正在进行的图片下载操作 76     [[SDWebImageManager sharedManager] cancelAll]; 77 } 78  79 - (void)applicationWillResignActive:(UIApplication *)application 80 { 81    82 } 83  84 /**程序进入后台的时候调用*/ 85 - (void)applicationDidEnterBackground:(UIApplication *)application 86 { 87     //提醒这个操作系统:当前这个应用程序需要在后台开启一个任务 88     //操作系统会运行这个应用程序在系统中保持运行状态(能够持续的时间是不确定的) 89     UIBackgroundTaskIdentifier taskID=[application  beginBackgroundTaskWithExpirationHandler:^{ 90         //后台运行的时间到期了,就会调用这个block 91         [application endBackgroundTask:taskID]; 92     }]; 93 } 94  95 - (void)applicationWillEnterForeground:(UIApplication *)application 96 { 97    98 } 99 100 - (void)applicationDidBecomeActive:(UIApplication *)application101 {102    103 }104 105 - (void)applicationWillTerminate:(UIApplication *)application106 {107    108 }109 110 @end

三、补充和修复

新的问题

(1)关于定时器:当滑动微博界面的时候,定时器就停止工作。原因是因为定时器是在项目的主线程处理的,默认情况下如果主线程正在处理UI事件的话是不会去处理定时器的。

告诉程序,尽量抽取时间爱哪去处理定时器,不应该在用户滚动页面的时候就把定时器给停了。

解决方法:把定时器添加到运行循环中,更改模式。

 1 - (void)viewDidLoad 2 { 3     [super viewDidLoad]; 4     //添加四个子控制器 5     [self addAllChildVcs]; 6  7     // 调整tabbar 8     [self addCustomTabBar]; 9     10     //设置定时器,每隔两秒就获取一次未读微博信息11    NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(getUnreadCount) userInfo:nil repeats:YES];12     [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];13 }

(2)关于多长时间发送一次请求

两秒发送一次请求太频繁,会很耗电。在开发中,设置为10秒钟左右就差不多了。

这样就带来了新的问题,下拉刷新之后,微博的提醒数字要稍微过一点儿时间才会清零。

所以,我们还需要监听下拉刷新事件,当下拉刷新成功的时候,立即对未读提醒进行清空。

YYHomeTableViewController.m文件中

 1 /** 2  *  提示用户最新的微博数量 3  * 4  *  @param count 最新的微博数量 5  */ 6 -(void)showNewStatusesCount:(int)count 7 { 8     //0.清零提醒数字 9     [UIApplication sharedApplication].applicationIconBadgeNumber -=self.tabBarItem.badgeValue.intValue;10     self.tabBarItem.badgeValue=http://www.mamicode.com/nil;11     12     //1.创建一个label13     UILabel *label=[[UILabel alloc]init];14     15     //2.设置label的文字

(3)当点击首页的时候,自动下拉刷新数据

说明:点击一次首页,回到之前所在的位置,点击两次首页,回到首页cell的顶部。

YYTabBarViewController.m文件

  1 //  2 //  YYTabBarViewController.m  3 //  4   5 #import "YYTabBarViewController.h"  6 #import "YYHomeTableViewController.h"  7 #import "YYDiscoverViewController.h"  8 #import "YYMessageViewController.h"  9 #import "YYProfileViewController.h" 10 #import "UIImage+Extension.h" 11 #import "YYNavigationViewController.h" 12 #import "YYTabBar.h" 13 #import "YYComposeViewController.h" 14 #import "YYUnreadCountResult.h" 15 #import "YYUnreadCountParam.h" 16 #import "YYUserTool.h" 17 #import "YYAccountTool.h" 18 @interface YYTabBarViewController ()<UITabBarControllerDelegate,YYTabBarDelegate> 19 @property(nonatomic,weak)YYHomeTableViewController *home; 20 @property(nonatomic,weak)YYMessageViewController *message; 21 @property(nonatomic,weak)YYProfileViewController *profile; 22 @property (nonatomic, weak) UIViewController *lastSelectedViewContoller; 23 @end 24  25 @implementation YYTabBarViewController 26  27  28 - (void)viewDidLoad 29 { 30     [super viewDidLoad]; 31     self.delegate=self;//自己成为自己的代理 32      33     //添加四个子控制器 34     [self addAllChildVcs]; 35  36     // 调整tabbar 37     [self addCustomTabBar]; 38      39     //设置定时器,每隔两秒就获取一次未读微博信息 40    NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(getUnreadCount) userInfo:nil repeats:YES]; 41     [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes]; 42 } 43  44 #pragma mark-代理方法 45 - (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UINavigationController *)viewController 46 { 47     UIViewController *vc = [viewController.viewControllers firstObject]; 48     if ([vc isKindOfClass:[YYHomeTableViewController class]]) { 49         if (self.lastSelectedViewContoller == vc) { 50             [self.home refresh:YES]; 51         } else { 52             [self.home refresh:NO]; 53         } 54     } 55      56     self.lastSelectedViewContoller = vc; 57 } 58  59 -(void)getUnreadCount 60 { 61     //1.请求参数 62     YYUnreadCountParam *param=[YYUnreadCountParam param]; 63     param.uid=[YYAccountTool accountModel].uid; 64      65      66     //2.获取未读微博信息 67     [YYUserTool unreadCountWithParam:param success:^(YYUnreadCountResult *result) { 68         //显示新的微博数 69         if (result.status==0) { 70             self.home.tabBarItem.badgeValue=http://www.mamicode.com/nil; 71         }else 72         { 73             self.home.tabBarItem.badgeValue=http://www.mamicode.com/[NSString stringWithFormat:@"%d",result.status]; 74         } 75          76         //显示消息未读数 77         if (result.messageCount==0) { 78             self.message.tabBarItem.badgeValue=http://www.mamicode.com/nil; 79         }else 80         { 81             self.message.tabBarItem.badgeValue=http://www.mamicode.com/[NSString stringWithFormat:@"%d",result.messageCount]; 82         } 83          84         //显示新的粉丝数量 85         if (result.follower==0) { 86             self.profile.tabBarItem.badgeValue=http://www.mamicode.com/nil; 87         }else 88         { 89             self.profile.tabBarItem.badgeValue=http://www.mamicode.com/[NSString stringWithFormat:@"%d",result.follower]; 90         } 91          92         //在图标上显示所有的未读数 93         [UIApplication sharedApplication].applicationIconBadgeNumber=result.totalCount; 94         YYLog(@"%d",result.totalCount); 95     } failure:^(NSError *error) { 96         YYLog(@"请求失败"); 97     }]; 98   99 }100 -(void)addAllChildVcs101 {102     YYHomeTableViewController *home=[[YYHomeTableViewController alloc]init];103     [self addOneChildVc:home title:@"首页" imageName:@"tabbar_home" selectedImageName:@"tabbar_home_selected"];104     self.home=home;105     self.lastSelectedViewContoller=home;106     107     YYMessageViewController *message=[[YYMessageViewController alloc]init];108     [self addOneChildVc:message title:@"消息" imageName:@"tabbar_message_center" selectedImageName:@"tabbar_message_center_selected"];109     self.message=message;110     111     YYDiscoverViewController *discover=[[YYDiscoverViewController alloc]init];112     [self addOneChildVc:discover title:@"发现" imageName:@"tabbar_discover" selectedImageName:@"tabbar_discover_selected"];113     114     YYProfileViewController *profile=[[YYProfileViewController alloc]init];115     [self addOneChildVc:profile title:@"" imageName:@"tabbar_profile" selectedImageName:@"tabbar_profile_selected"];116     self.profile=profile;117 }118 119 -(void)addCustomTabBar120 {121     YYTabBar *customTabBar = [[YYTabBar alloc] init];122     //设置代理123     customTabBar.delegate=self;124     // 更换系统自带的tabbar125     [self setValue:customTabBar forKeyPath:@"tabBar"];126 }127 128 129 #pragma mark-YYTabBarDelegate130 -(void)tabBarDidClickedPlusButton:(YYTabBar *)tabBar131 {132     //弹出发微博的控制器133     YYComposeViewController *compose=[[YYComposeViewController alloc]init];134     YYNavigationViewController *nav=[[YYNavigationViewController alloc]initWithRootViewController:compose];135     [self presentViewController:nav animated:YES completion:nil];136 }137 138 139 /**140  *  添加一个子控制器141  *142  *  @param childVC           子控制对象143  *  @param title             标题144  *  @param imageName         图标145  *  @param selectedImageName 选中时的图标146  */147 -(void)addOneChildVc:(UIViewController *)childVc title:(NSString *)title imageName:(NSString *)imageName selectedImageName:(NSString *)selectedImageName148 {149     //随机设置子控制器的背景颜色150 //    childVc.view.backgroundColor=YYRandomColor;151     152     //设置标题153     childVc.title=title;  //相当于设置了后两者的标题154 155     156     //设置图标157     childVc.tabBarItem.image=[UIImage imageWithName:imageName];158     //设置选中时的图标159     UIImage *selectedImage=[UIImage imageWithName:selectedImageName];160     161     //设置tabBarItem普通状态下文字的颜色162     NSMutableDictionary *textAttrs=[NSMutableDictionary dictionary];163     textAttrs[UITextAttributeTextColor]=[UIColor blackColor];164     textAttrs[UITextAttributeFont]=[UIFont systemFontOfSize:10];165     [childVc.tabBarItem setTitleTextAttributes:textAttrs forState:UIControlStateNormal];166     167     //设置tabBarItem普通状态下文字的颜色168     NSMutableDictionary *selectedtextAttrs=[NSMutableDictionary dictionary];169     selectedtextAttrs[UITextAttributeTextColor]=[UIColor orangeColor];170     [childVc.tabBarItem setTitleTextAttributes:selectedtextAttrs forState:UIControlStateSelected];171     172     if (iOS7) {173         // 声明这张图片用原图(别渲染)174         selectedImage = [selectedImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];175     }176     childVc.tabBarItem.selectedImage = selectedImage;177     178      // 添加为tabbar控制器的子控制器179     YYNavigationViewController *nav=[[YYNavigationViewController alloc]initWithRootViewController:childVc];180     181     [self addChildViewController:nav];182 183 }184 185 @end

YYHomeTableViewController.h文件

 1 // 2 //  YYHomeTableViewController.h 3 // 4  5 #import <UIKit/UIKit.h> 6  7 @interface YYHomeTableViewController : UITableViewController 8  9 /**10  *  刷新11  */12 - (void)refresh:(BOOL)fromSelf;13 @end

YYHomeTableViewController.m文件

  1 //  2 //  YYHomeTableViewController.m  3 //  4   5 #import "YYHomeTableViewController.h"  6 #import "YYOneViewController.h"  7 #import "YYTitleButton.h"  8 #import "YYPopMenu.h"  9 #import "YYAccountModel.h" 10 #import "YYAccountTool.h" 11 //#import "AFNetworking.h" 12 #import "UIImageView+WebCache.h" 13 #import "YYUserModel.h" 14 #import "YYStatusModel.h" 15 #import "MJExtension.h" 16 #import "YYloadStatusesFooter.h" 17 //#import "YYHttpTool.h" 18 #import "YYHomeStatusesParam.h" 19 #import "YYHomeStatusesResult.h" 20 #import "YYStatusTool.h" 21 #import "YYUserInfoParam.h" 22 #import "YYUserTool.h" 23  24 @interface YYHomeTableViewController ()<YYPopMenuDelegate> 25 @property(nonatomic,assign)BOOL down; 26 @property(nonatomic,strong)NSMutableArray *statuses; 27 @property(nonatomic,strong)YYloadStatusesFooter *footer; 28 @property(nonatomic,strong) YYTitleButton *titleButton; 29 @property (nonatomic, weak) UIRefreshControl *refreshControl; 30 @end 31  32 @implementation YYHomeTableViewController 33  34 #pragma mark- 懒加载 35 -(NSMutableArray *)statuses 36 { 37     if (_statuses==nil) { 38         _statuses=[NSMutableArray array]; 39     } 40     return _statuses; 41 } 42 - (void)viewDidLoad 43 { 44     [super viewDidLoad]; 45      46     //设置导航栏内容 47     [self setupNavBar]; 48      49     //集成刷新控件 50     [self setupRefresh]; 51      52     //设置用户的昵称为标题 53     //先显示首页标题,延迟两秒之后变换成用户昵称 54     dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ 55         [self setupUserInfo]; 56     }); 57 } 58  59 /** 60  *设置用户的昵称为标题 61  */ 62 -(void)setupUserInfo 63 { 64     //1.封装请求参数 65 //    YYUserInfoParam *params=[[YYUserInfoParam alloc]init]; 66 //    params.access_token=[YYAccountTool accountModel].access_token; 67     YYUserInfoParam *params=[YYUserInfoParam param]; 68     params.uid=[YYAccountTool accountModel].uid; 69      70     //2.发送网络请求 71     [YYUserTool userInfoWithParam:params success:^(YYUserInfoResult *result) { 72          73         //字典转模型 74         YYUserModel *user=result; 75          76         //设置标题 77         [self.titleButton setTitle:user.name forState:UIControlStateNormal]; 78        // 存储账号信息(需要先拿到账号) 79         YYAccountModel *account=[YYAccountTool accountModel]; 80         account.name=user.name; 81         //存储 82         [YYAccountTool save:account]; 83     } failure:^(NSError *error) { 84          YYLog(@"请求失败"); 85     }]; 86 } 87  88 //集成刷新控件 89 -(void)setupRefresh 90 { 91     // 1.添加下拉刷新控件 92     UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init]; 93     [self.tableView addSubview:refreshControl]; 94     self.refreshControl=refreshControl; 95      96     //2.监听状态 97     [refreshControl addTarget:self action:(@selector(refreshControlStateChange:)) forControlEvents:UIControlEventValueChanged]; 98      99     //3.让刷新控件自动进入到刷新状态100     [refreshControl beginRefreshing];101     102     //4.手动调用方法,加载数据103     //模拟网络延迟,延迟2.0秒104     dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{105         [self refreshControlStateChange:refreshControl];106     });107     108     //5.上拉刷新数据109     YYloadStatusesFooter *footer=[YYloadStatusesFooter loadFooter];110     self.tableView.tableFooterView=footer;111     self.footer=footer;112 }113 114 /**115  *  当下拉刷新控件进入刷新状态(转圈圈)的时候会自动调用116  */117 -(void)refreshControlStateChange:(UIRefreshControl *)refreshControl118 {119     [self loadNewStatuses:refreshControl];120 }121 122 #pragma mark- 刷新123 -(void)refresh:(BOOL)fromSelf124 {125     if (self.tabBarItem.badgeValue) {//如果有数字126         //转圈圈127         [self.refreshControl beginRefreshing];128         129         //刷新数据130         [self loadNewStatuses:self.refreshControl];131     }else if(fromSelf)          //  没有数字132     {133         //让表格回到最顶部134         NSIndexPath *firstRow=[NSIndexPath indexPathForItem:0 inSection:0];135         [self.tableView scrollToRowAtIndexPath:firstRow atScrollPosition:UITableViewScrollPositionTop animated:YES];136         137     }138 }139 #pragma mark-加载微博数据140 -(void)loadNewStatuses:(UIRefreshControl *)refreshControl141 {142     //1.封装请求参数143 //    YYHomeStatusesParam *param=[[YYHomeStatusesParam alloc]init];144 //    param.access_token=[YYAccountTool accountModel].access_token;145     YYHomeStatusesParam *param=[YYHomeStatusesParam param];146     YYStatusModel *firstStatus=[self.statuses firstObject];147     if (firstStatus) {148         param.since_id=@([firstStatus.idstr longLongValue]);149     }150     151     //2.加载微博数据152     [YYStatusTool homeStatusesWithParam:param success:^(YYHomeStatusesResult *result) {153         //获取最新的微博数组154         NSArray *newStatuses=result.statuses;155         156         //把新数据添加到旧数据的前面157         NSRange range=NSMakeRange(0, newStatuses.count);158         NSIndexSet *indexSet=[NSIndexSet indexSetWithIndexesInRange:range];159         [self.statuses insertObjects:newStatuses atIndexes:indexSet];160         YYLog(@"刷新了--%d条新数据",newStatuses.count);161         162         //重新刷新表格163         [self.tableView reloadData];164         //让刷新控件停止刷新(回复默认的状态)165         [refreshControl endRefreshing];166         [self showNewStatusesCount:newStatuses.count];167 168     } failure:^(NSError *error) {169         YYLog(@"请求失败");170         //让刷新控件停止刷新(回复默认的状态)171         [refreshControl endRefreshing];172 173     }];174     175 }176 177 /**178  *  加载更多的微博数据179  */180 - (void)loadMoreStatuses181 {182     //1.封装请求参数183 //    YYHomeStatusesParam *param=[[YYHomeStatusesParam alloc]init];184 //    param.access_token=[YYAccountTool accountModel].access_token;185     YYHomeStatusesParam *param=[YYHomeStatusesParam param];186     YYStatusModel *lastStatus=[self.statuses lastObject];187     if (lastStatus) {188         param.max_id=@([lastStatus.idstr longLongValue]-1);189     }190     191     //2.发送网络请求192     [YYStatusTool homeStatusesWithParam:param success:^(YYHomeStatusesResult *result) {193         194         //获取最新的微博数组195         NSArray *newStatuses=result.statuses;196         // 将新数据插入到旧数据的最后面197         [self.statuses addObjectsFromArray:newStatuses];198         // 重新刷新表格199         [self.tableView reloadData];200         // 让刷新控件停止刷新(恢复默认的状态)201         [self.footer endRefreshing];202     } failure:^(NSError *error) {203         YYLog(@"请求失败--%@", error);204         // 让刷新控件停止刷新(恢复默认的状态)205         [self.footer endRefreshing];206     }];207 }208 209 /**210  *  提示用户最新的微博数量211  *212  *  @param count 最新的微博数量213  */214 -(void)showNewStatusesCount:(int)count215 {216     //0.清零提醒数字217     [UIApplication sharedApplication].applicationIconBadgeNumber -=self.tabBarItem.badgeValue.intValue;218     self.tabBarItem.badgeValue=http://www.mamicode.com/nil;219     220     //1.创建一个label221     UILabel *label=[[UILabel alloc]init];222     223     //2.设置label的文字224     if (count) {225         label.text=[NSString stringWithFormat:@"共有%d条新的微博数据",count];226     }else227     {228         label.text=@"没有最新的微博数据";229     }230     231     //3.设置label的背景和对其等属性232     label.backgroundColor=[UIColor colorWithPatternImage:[UIImage imageWithName:@"timeline_new_status_background"]];233     label.textAlignment=UITextAlignmentCenter;234     label.textColor=[UIColor whiteColor];235     236     //4.设置label的frame237     label.x=0;238     label.width=self.view.width;239     label.height=35;240 //    label.y=64-label.height;241    label.y=self.navigationController.navigationBar.height+20-label.height;242     243     //5.把lable添加到导航控制器的View上244 //    [self.navigationController.view addSubview:label];245     //把label添加到导航控制器上,显示在导航栏的下面246     [self.navigationController.view insertSubview:label belowSubview:self.navigationController.navigationBar];247     248     //6.设置动画效果249     CGFloat duration=0.75;250     //设置提示条的透明度251     label.alpha=0.0;252    [UIView animateWithDuration:duration animations:^{253        //往下移动一个label的高度254        label.transform=CGAffineTransformMakeTranslation(0, label.height);255        label.alpha=1.0;256    } completion:^(BOOL finished) {//向下移动完毕257        258        //延迟delay秒的时间后,在执行动画259        CGFloat delay=0.5;260        261        [UIView animateKeyframesWithDuration:duration delay:delay options:UIViewAnimationOptionCurveEaseOut animations:^{262            263            //恢复到原来的位置264            label.transform=CGAffineTransformIdentity;265            label.alpha=0.0;266            267        } completion:^(BOOL finished) {268            269            //删除控件270            [label removeFromSuperview];271        }];272    }];273 }274 275 /**276  UIViewAnimationOptionCurveEaseInOut            = 0 << 16, // 开始:由慢到快,结束:由快到慢277  UIViewAnimationOptionCurveEaseIn               = 1 << 16, // 由慢到块278  UIViewAnimationOptionCurveEaseOut              = 2 << 16, // 由快到慢279  UIViewAnimationOptionCurveLinear               = 3 << 16, // 线性,匀速280  */281 282 /**设置导航栏内容*/283 -(void)setupNavBar284 {285     self.navigationItem.leftBarButtonItem=[UIBarButtonItem itemWithImageName:@"navigationbar_friendsearch" highImageName:@"navigationbar_friendsearch_highlighted" target:self action:@selector(friendsearch)];286     self.navigationItem.rightBarButtonItem=[UIBarButtonItem itemWithImageName:@"navigationbar_pop" highImageName:@"navigationbar_pop_highlighted" target:self action:@selector(pop)];287     288     //设置导航栏按钮289     YYTitleButton *titleButton=[[YYTitleButton alloc]init];290     291     //设置尺寸292 //    titleButton.width=100;293         titleButton.height=35;294 295     //设置文字296     YYAccountModel *account= [YYAccountTool accountModel];297     NSString *name=account.name;298     NSLog(@"%@",name);299 //    name=@"yangye";300     //判断:如果name有值(上一次登录的用户名),那么就使用上次的,如果没有那么就设置为首页301     if (name) {302         [titleButton setTitle:name forState:UIControlStateNormal];303     }else{304         [titleButton setTitle:@"首页" forState:UIControlStateNormal];305     }306     //设置图标307     [titleButton setImage:[UIImage imageWithName:@"navigationbar_arrow_down"] forState:UIControlStateNormal];308     //设置背景309     [titleButton setBackgroundImage:[UIImage resizedImage:@"navigationbar_filter_background_highlighted"] forState:UIControlStateHighlighted];310     311     //设置尺寸312 //    titleButton.width=100;313 //    titleButton.height=35;314     //监听按钮的点击事件315     [titleButton addTarget:self action:@selector(titleButtonClick:) forControlEvents:UIControlEventTouchUpInside];316     self.navigationItem.titleView=titleButton;317     self.titleButton=titleButton;318 }319 -(void)titleButtonClick:(UIButton *)titleButton320 {321 322         [titleButton setImage:[UIImage imageWithName:@"navigationbar_arrow_up"] forState:UIControlStateNormal];323         324         UITableView *tableView=[[UITableView alloc]init];325         [tableView setBackgroundColor:[UIColor yellowColor]];326         YYPopMenu *menu=[YYPopMenu popMenuWithContentView:tableView];327         [menu showInRect:CGRectMake(60, 55, 200, 200)];328         menu.dimBackground=YES;329 330     menu.arrowPosition=YYPopMenuArrowPositionRight;331         menu.delegate=self;332 }333 334 335 #pragma mark-YYPopMenuDelegate336 //弹出菜单337 -(void)popMenuDidDismissed:(YYPopMenu *)popMenu338 {339     YYTitleButton *titleButton=(YYTitleButton *)self.navigationItem.titleView;340     [titleButton setImage:[UIImage imageWithName:@"navigationbar_arrow_down"] forState:UIControlStateNormal];341 }342 -(void)pop343 {344     YYLog(@"---POP---");345 }346 -(void)friendsearch347 {348     //跳转到one这个子控制器界面349     YYOneViewController *one=[[YYOneViewController alloc]init];350     one.title=@"One";351     //拿到当前控制器352     [self.navigationController pushViewController:one animated:YES];353     354 }355 356 #pragma mark - Table view data source357 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section358 {359 #warning 监听tableView每次显示数据的过程360     //在tableView显示之前,判断有没有数据,如有有数据那么就显示底部视图361     self.footer.hidden=self.statuses.count==0;362     return self.statuses.count;363 }364 365 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath366 {367     static NSString *ID = @"cell";368     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];369     if (!cell) {370         cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];371     }372     373       //取出这行对应的微博字典数据,转换为数据模型374     YYStatusModel *status=self.statuses[indexPath.row];375     cell.textLabel.text=status.text;376     cell.detailTextLabel.text=status.user.name;377     NSString *imageUrlStr=status.user.profile_image_url;378     [cell.imageView setImageWithURL:[NSURL URLWithString:imageUrlStr] placeholderImage:[UIImage imageWithName:@"avatar_default_small"]];379     380     return cell;381 }382 383 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath384 {385     //点击cell的时候,跳到下一个界面386     UIViewController *newVc = [[UIViewController alloc] init];387     newVc.view.backgroundColor = [UIColor redColor];388     newVc.title = @"新控制器";389     [self.navigationController pushViewController:newVc animated:YES];390 }391 392 #pragma mark-代理方法393 - (void)scrollViewDidScroll:(UIScrollView *)scrollView394 {395     if (self.statuses.count <= 0 || self.footer.isRefreshing) return;396     397     // 1.差距398     CGFloat delta = scrollView.contentSize.height - scrollView.contentOffset.y;399     // 刚好能完整看到footer的高度400     CGFloat sawFooterH = self.view.height - self.tabBarController.tabBar.height;401     402     // 2.如果能看见整个footer403     if (delta <= (sawFooterH - 0)) {404         // 进入上拉刷新状态405         [self.footer beginRefreshing];406         407         dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{408             // 加载更多的微博数据409             [self loadMoreStatuses];410         });411     }412 }413 @end