分享

iOS开发项目篇

 最初九月雪 2015-01-10

iOS开发项目篇—30下拉刷新

一、网络监控

当应用所处的网络环境不好的时候,获取不到相应的网络数据,考虑到用户对应用的使用体验,有必要对网络的状况进行监听。
在程序启动完的时候,监控网络
 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 
16 @implementation YYAppDelegate
17 
18 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
19 {
20  
21    //1.创建窗口
22     self.window=[[UIWindow alloc]init];
23     self.window.frame=[UIScreen mainScreen].bounds;
24     
25     
26     //2.显示窗口(主窗口)
27     [self.window makeKeyAndVisible];
28     
29     //3.设置窗口的根控制器
30     YYAccountModel *account=[YYAccountTool accountModel];
31     
32     if (account) {  //  存在成功授权的账号信息
33         [YYControllerTool chooseRootViewController];
34     }else  //没有登陆过
35     {
36         self.window.rootViewController=[[YYOAuthViewController alloc]init];
37     }
38     
39     //4.监控网络状态
40     AFNetworkReachabilityManager *mgr=[AFNetworkReachabilityManager sharedManager];
41     //当网络状态改变的时候,就会调用
42     [mgr setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
43         switch (status) {
44             case AFNetworkReachabilityStatusUnknown://未知网络
45             case AFNetworkReachabilityStatusNotReachable://没有网络
46                 YYLog(@"没有网络(断网)");
47                 [MBProgressHUD showError:@"网络异常,请检查网络设置!"];
48                 break;
49             case AFNetworkReachabilityStatusReachableViaWWAN://手机自带网络
50                 YYLog(@"手机自带网络");
51                 break;
52             case AFNetworkReachabilityStatusReachableViaWiFi://WIFI
53                 YYLog(@"WIFI");
54                 break;
55         }
56     }];
57     //开始监控
58     [mgr startMonitoring];
59     return YES;
60 }
61 
62 
63 - (void)applicationDidReceiveMemoryWarning:(UIApplication *)application
64 {
65     // 赶紧清除所有的内存缓存
66     [[SDImageCache sharedImageCache] clearMemory];
67     
68     // 赶紧停止正在进行的图片下载操作
69     [[SDWebImageManager sharedManager] cancelAll];
70
复制代码

二、下拉刷新数据的简单说明

代码:

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 
 17 @interface YYHomeTableViewController ()<YYPopMenuDelegate>
 18 @property(nonatomic,assign)BOOL down;
 19 @property(nonatomic,strong)NSArray *statuses;
 20 @end
 21 
 22 @implementation YYHomeTableViewController
 23 
 24 - (void)viewDidLoad
 25 {
 26     [super viewDidLoad];
 27     
 28     //设置导航栏内容
 29     [self setupNavBar];
 30     
 31     //加载最新数据
 32     [self loadNewStatus];
 33     
 34     //集成刷新控件
 35     [self setupRefresh];
 36 }
 37 
 38 //集成刷新控件
 39 -(void)setupRefresh
 40 {
 41     // 1.添加下拉刷新控件
 42     UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
 43     [self.tableView addSubview:refreshControl];
 44     
 45     [self loadNewStatus];
 46 }
 47 
 48 /**加载最新微博数据*/
 49 -(void)loadNewStatus
 50 {
 51     //1.获得请求管理者
 52     AFHTTPRequestOperationManager *mgr = [AFHTTPRequestOperationManager manager];
 53     
 54     //2.封装请求参数
 55     
 56     NSMutableDictionary *params=[NSMutableDictionary dictionary];
 57     params[@"access_token"] =[YYAccountTool accountModel].access_token;
 58     //设置请求返回3天数据
 59     params[@"count"]=@12;
 60  
 61     
 62     //3.发送Post请求
 63    // url:https://api.weibo.com/2/statuses/home_timeline.json
 64     [mgr GET:@"https://api.weibo.com/2/statuses/home_timeline.json" parameters:params success:^(AFHTTPRequestOperation *operation, NSDictionary*accountDict) {
 65 
 66         self.statuses=accountDict[@"statuses"];
 67         
 68         // 微博字典 -- 数组
 69         NSArray *statusDictArray = accountDict[@"statuses"];
 70         
 71         //微博字典数组---》微博模型数组
 72         self.statuses=[YYStatusModel objectArrayWithKeyValuesArray:statusDictArray];
 73         
 74         //重新刷新表格
 75         [self.tableView reloadData];
 76     } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
 77         YYLog(@"请求失败");
 78     }];
 79     
 80 }
 81 /**设置导航栏内容*/
 82 -(void)setupNavBar
 83 {
 84     self.navigationItem.leftBarButtonItem=[UIBarButtonItem itemWithImageName:@"navigationbar_friendsearch" highImageName:@"navigationbar_friendsearch_highlighted" target:self action:@selector(friendsearch)];
 85     self.navigationItem.rightBarButtonItem=[UIBarButtonItem itemWithImageName:@"navigationbar_pop" highImageName:@"navigationbar_pop_highlighted" target:self action:@selector(pop)];
 86     
 87     //设置导航栏按钮
 88     YYTitleButton *titleButton=[[YYTitleButton alloc]init];
 89     //设置文字
 90     [titleButton setTitle:@"首页" forState:UIControlStateNormal];
 91     //设置图标
 92     [titleButton setImage:[UIImage imageWithName:@"navigationbar_arrow_down"] forState:UIControlStateNormal];
 93     //设置背景
 94     [titleButton setBackgroundImage:[UIImage resizedImage:@"navigationbar_filter_background_highlighted"] forState:UIControlStateHighlighted];
 95     
 96     //设置尺寸
 97     titleButton.width=100;
 98     titleButton.height=35;
 99     //监听按钮的点击事件
100     [titleButton addTarget:self action:@selector(titleButtonClick:) forControlEvents:UIControlEventTouchUpInside];
101     self.navigationItem.titleView=titleButton;
102 }
103 -(void)titleButtonClick:(UIButton *)titleButton
104 {
105 
106         [titleButton setImage:[UIImage imageWithName:@"navigationbar_arrow_up"] forState:UIControlStateNormal];
107         
108         UITableView *tableView=[[UITableView alloc]init];
109         [tableView setBackgroundColor:[UIColor yellowColor]];
110         YYPopMenu *menu=[YYPopMenu popMenuWithContentView:tableView];
111         [menu showInRect:CGRectMake(60, 55, 200, 200)];
112         menu.dimBackground=YES;
113 
114     menu.arrowPosition=YYPopMenuArrowPositionRight;
115         menu.delegate=self;
116 }
117 
118 
119 #pragma mark-YYPopMenuDelegate
120 //弹出菜单
121 -(void)popMenuDidDismissed:(YYPopMenu *)popMenu
122 {
123     YYTitleButton *titleButton=(YYTitleButton *)self.navigationItem.titleView;
124     [titleButton setImage:[UIImage imageWithName:@"navigationbar_arrow_down"] forState:UIControlStateNormal];
125 }
126 -(void)pop
127 {
128     YYLog(@"---POP---");
129 }
130 -(void)friendsearch
131 {
132     //跳转到one这个子控制器界面
133     YYOneViewController *one=[[YYOneViewController alloc]init];
134     one.title=@"One";
135     //拿到当前控制器
136     [self.navigationController pushViewController:one animated:YES];
137     
138 }
139 
140 #pragma mark - Table view data source
141 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
142 {
143     return self.statuses.count;
144 }
145 
146 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
147 {
148     static NSString *ID = @"cell";
149     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
150     if (!cell) {
151         cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];
152     }
153     
154       //取出这行对应的微博字典数据,转换为数据模型
155     YYStatusModel *status=self.statuses[indexPath.row];
156     cell.textLabel.text=status.text;
157     cell.detailTextLabel.text=status.user.name;
158     NSString *imageUrlStr=status.user.profile_image_url;
159     [cell.imageView setImageWithURL:[NSURL URLWithString:imageUrlStr] placeholderImage:[UIImage imageWithName:@"avatar_default_small"]];
160     
161     return cell;
162 }
163 
164 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
165 {
166     //点击cell的时候,跳到下一个界面
167     UIViewController *newVc = [[UIViewController alloc] init];
168     newVc.view.backgroundColor = [UIColor redColor];
169     newVc.title = @"新控制器";
170     [self.navigationController pushViewController:newVc animated:YES];
171 }
172 
173 @end
复制代码

 

实现效果:

   

说明:前者为ios7中得效果。后者为ios6中得效果。

提示:不能直接调用“加载最新微博数据”这个方法,因为如果调用这个方法,那么会重新发送请求给服务器,服务器接受到数据后会直接覆盖以前数组中得数据。

 

三、下拉刷新的完善

1.关于请求参数

since_id:返回比这个值更大的微博。

提示:id在数据库中通常是自动增长的。

关于id的网络请求处理:

复制代码
 1    //2.封装请求参数
 2     
 3     NSMutableDictionary *params=[NSMutableDictionary dictionary];
 4     params[@"access_token"] =[YYAccountTool accountModel].access_token;
 5     // since_id     false     int64     若指定此参数,则返回ID比since_id大的微博(即比since_id时间晚的微博),默认为0。
 6     //取出当前微博模型中的第一条数据,获取第一条数据的id
 7     //不要使用self.statuses[0],这样会产生数组越界问题
 8     YYStatusModel *firstStatus=[self.statuses firstObject];
 9     if (firstStatus) {
10         params[@"since_id"]=firstStatus.idstr;
11     }
复制代码

说明:如果是直接刷新的话,那么每次获取的数据会直接覆盖掉以前的数据,比如现在最大的id值为10,刷新数据,如果只有两条新的数据,那么微博模型中就只有11,12数据。

解决:更改数组为可变数组,然后对刷新获取的数据进行拼接。

 插入:

 (1) [self.statuses insertObject:newStatuses atIndex:0];这种方式是把整个数组作为第一个元素插入到原来的数组中,即数组中的第一个元素是数组。

 (2)[self.statuses insertObjects:newStatuses atIndexes:0];这种方式是把数组中的元素一次插入到数组中。

实现代码:

 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 
 17 @interface YYHomeTableViewController ()<YYPopMenuDelegate>
 18 @property(nonatomic,assign)BOOL down;
 19 @property(nonatomic,strong)NSMutableArray *statuses;
 20 @end
 21 
 22 @implementation YYHomeTableViewController
 23 
 24 #pragma mark- 懒加载
 25 -(NSMutableArray *)statuses
 26 {
 27     if (_statuses==nil) {
 28         _statuses=[NSMutableArray array];
 29     }
 30     return _statuses;
 31 }
 32 - (void)viewDidLoad
 33 {
 34     [super viewDidLoad];
 35     
 36     //设置导航栏内容
 37     [self setupNavBar];
 38     
 39 //    //加载最新数据
 40 //    [self loadNewStatus];
 41     
 42     //集成刷新控件
 43     [self setupRefresh];
 44 }
 45 
 46 //集成刷新控件
 47 -(void)setupRefresh
 48 {
 49     // 1.添加下拉刷新控件
 50     UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
 51     [self.tableView addSubview:refreshControl];
 52     
 53     [refreshControl addTarget:self action:(@selector(refreshControlStateChange:)) forControlEvents:UIControlEventValueChanged];
 54 //    [self loadNewStatus];
 55 }
 56 
 57 /**
 58  *  当下拉刷新控件进入刷新状态(转圈圈)的时候会自动调用
 59  */
 60 -(void)refreshControlStateChange:(UIRefreshControl *)refreshControl
 61 {
 62     //1.获得请求管理者
 63     AFHTTPRequestOperationManager *mgr = [AFHTTPRequestOperationManager manager];
 64     
 65     //2.封装请求参数
 66     
 67     NSMutableDictionary *params=[NSMutableDictionary dictionary];
 68     params[@"access_token"] =[YYAccountTool accountModel].access_token;
 69     
 70     // since_id     false     int64     若指定此参数,则返回ID比since_id大的微博(即比since_id时间晚的微博),默认为0。
 71     //取出当前微博模型中的第一条数据,获取第一条数据的id
 72     //不要使用self.statuses[0],这样会产生数组越界问题
 73     YYStatusModel *firstStatus=[self.statuses firstObject];
 74     if (firstStatus) {
 75         params[@"since_id"]=firstStatus.idstr;
 76     }
 77     
 78     //设置请求返回的数据
 79 //    params[@"count"]=@12;
 80     
 81     
 82     //3.发送Get请求
 83     [mgr GET:@"https://api.weibo.com/2/statuses/home_timeline.json" parameters:params success:^(AFHTTPRequestOperation *operation, NSDictionary*accountDict) {
 84         
 85 //        self.statuses=accountDict[@"statuses"];
 86         
 87         // 微博字典 -- 数组
 88         NSArray *statusDictArray = accountDict[@"statuses"];
 89         
 90         //微博字典数组---》微博模型数组
 91        NSArray *newStatuses =[YYStatusModel objectArrayWithKeyValuesArray:statusDictArray];
 92         
 93         //把新数据添加到旧数据的前面
 94         NSRange range=NSMakeRange(0, newStatuses.count);
 95         NSIndexSet *indexSet=[NSIndexSet indexSetWithIndexesInRange:range];
 96         [self.statuses insertObjects:newStatuses atIndexes:indexSet];
 97         YYLog(@"刷新了--%d条新数据",newStatuses.count);
 98         
 99         //重新刷新表格
100         [self.tableView reloadData];
101         //让刷新控件停止刷新(回复默认的状态)
102         [refreshControl endRefreshing];
103       
104     } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
105         YYLog(@"请求失败");
106         //让刷新控件停止刷新(回复默认的状态)
107         [refreshControl endRefreshing];
108     }];
109 
110 }
111 
112 
113 /**设置导航栏内容*/
114 -(void)setupNavBar
115 {
116     self.navigationItem.leftBarButtonItem=[UIBarButtonItem itemWithImageName:@"navigationbar_friendsearch" highImageName:@"navigationbar_friendsearch_highlighted" target:self action:@selector(friendsearch)];
117     self.navigationItem.rightBarButtonItem=[UIBarButtonItem itemWithImageName:@"navigationbar_pop" highImageName:@"navigationbar_pop_highlighted" target:self action:@selector(pop)];
118     
119     //设置导航栏按钮
120     YYTitleButton *titleButton=[[YYTitleButton alloc]init];
121     //设置文字
122     [titleButton setTitle:@"首页" forState:UIControlStateNormal];
123     //设置图标
124     [titleButton setImage:[UIImage imageWithName:@"navigationbar_arrow_down"] forState:UIControlStateNormal];
125     //设置背景
126     [titleButton setBackgroundImage:[UIImage resizedImage:@"navigationbar_filter_background_highlighted"] forState:UIControlStateHighlighted];
127     
128     //设置尺寸
129     titleButton.width=100;
130     titleButton.height=35;
131     //监听按钮的点击事件
132     [titleButton addTarget:self action:@selector(titleButtonClick:) forControlEvents:UIControlEventTouchUpInside];
133     self.navigationItem.titleView=titleButton;
134 }
135 -(void)titleButtonClick:(UIButton *)titleButton
136 {
137 
138         [titleButton setImage:[UIImage imageWithName:@"navigationbar_arrow_up"] forState:UIControlStateNormal];
139         
140         UITableView *tableView=[[UITableView alloc]init];
141         [tableView setBackgroundColor:[UIColor yellowColor]];
142         YYPopMenu *menu=[YYPopMenu popMenuWithContentView:tableView];
143         [menu showInRect:CGRectMake(60, 55, 200, 200)];
144         menu.dimBackground=YES;
145 
146     menu.arrowPosition=YYPopMenuArrowPositionRight;
147         menu.delegate=self;
148 }
149 
150 
151 #pragma mark-YYPopMenuDelegate
152 //弹出菜单
153 -(void)popMenuDidDismissed:(YYPopMenu *)popMenu
154 {
155     YYTitleButton *titleButton=(YYTitleButton *)self.navigationItem.titleView;
156     [titleButton setImage:[UIImage imageWithName:@"navigationbar_arrow_down"] forState:UIControlStateNormal];
157 }
158 -(void)pop
159 {
160     YYLog(@"---POP---");
161 }
162 -(void)friendsearch
163 {
164     //跳转到one这个子控制器界面
165     YYOneViewController *one=[[YYOneViewController alloc]init];
166     one.title=@"One";
167     //拿到当前控制器
168     [self.navigationController pushViewController:one animated:YES];
169     
170 }
171 
172 #pragma mark - Table view data source
173 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
174 {
175     return self.statuses.count;
176 }
177 
178 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
179 {
180     static NSString *ID = @"cell";
181     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
182     if (!cell) {
183         cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];
184     }
185     
186       //取出这行对应的微博字典数据,转换为数据模型
187     YYStatusModel *status=self.statuses[indexPath.row];
188     cell.textLabel.text=status.text;
189     cell.detailTextLabel.text=status.user.name;
190     NSString *imageUrlStr=status.user.profile_image_url;
191     [cell.imageView setImageWithURL:[NSURL URLWithString:imageUrlStr] placeholderImage:[UIImage imageWithName:@"avatar_default_small"]];
192     
193     return cell;
194 }
195 
196 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
197 {
198     //点击cell的时候,跳到下一个界面
199     UIViewController *newVc = [[UIViewController alloc] init];
200     newVc.view.backgroundColor = [UIColor redColor];
201     newVc.title = @"新控制器";
202     [self.navigationController pushViewController:newVc animated:YES];
203 }
204 
205 @end
复制代码

 

重要错误

错误提示:数据插入到了一个不可变对象中。

提示:在拿到刷新的数据后,应该让刷新控件停止刷新。

说明:刷新控件,在ios6以后可以使用。

注意:账号并没有通过新浪的审核,所以调用接口的频率是有限制的。

执行显示:

打印查看:

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多