这个页面要讲述的是用户的粉丝列表,下面是效果图:

可以看到这个视图明显也是一个tableview,在每一个cell中包含的有三个部分的内容:粉丝头像image,粉丝昵称label,我和粉丝之间的相互关注情况button。

在这个页面我们主要处理的内容有:① 粉丝列表数据的获取  ②tableview视图界面的组织(重点是:添加关注和取消关注)

(1)首先是获取粉丝列表数据,这部分内容没有什么好说的,就是些JSON数据,然后解析。调用的API:https://api.weibo.com/2/friendships/followers.json。其中有一个点是需要注意的。我们注意到其中API请求的参数:

count false int 单页返回的记录条数,默认为50,最大不超过200。
cursor false int 返回结果的游标,下一页用返回值里的next_cursor,上一页用previous_cursor,默认为0。

可以知道一次数据请求是以页的方式返回的,每一页返回count条数的粉丝记录,这个和前面微博内容的返回的差不多的,都是以页为单位返回,但是这里有一个比较特殊的是,在这个API的数据请求中没有page这个参数,而是用到了cursor这个参数,这个参数开始是0,以后每一次请求后获取的数据中就有next_cursor这个返回值,用它来为cursor赋值,就可以继续获取接下去的数据了,如果粉丝数据已经全部获取到了,那么这个值返回就又是0了。那么我们在继续加载的时候就可以添加一个判断,判断next_cursor是否为0,如果不为0,说明粉丝列表还没有加载完毕,可以继续请求加载;如果为0,则说明所有的粉丝数据都已经加载了,这时就不要继续再加载了。

下面通过代码看看吧!

  1. - (void) loadFollersDataWithCursor:(int) cursor {
  2. dispatch_async(dispatch_get_global_queue(0, 0), ^{
  3. dispatch_sync(dispatch_get_global_queue(0, 0), ^{
  4. hud = [[MBProgressHUD alloc] init];
  5. hud.dimBackground = YES;
  6. hud.labelText = @"正在加载数据...";
  7. [hud show:YES];
  8. [self.view addSubview:hud];
  9. //同步GET请求粉丝数据
  10. NSURLRequest *request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:[InfoForSina returnFollowersUrlStringWithCursor:cursor]]];
  11. NSError *error;
  12. NSData *followersData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:&error];
  13. //使用JSONKit解析数据
  14. NSString *follwersString = [[NSString alloc] initWithData:followersData encoding:NSUTF8StringEncoding];
  15. NSDictionary *followersDictionary = [follwersString objectFromJSONString];
  16. NSArray *followersArray = [followersDictionary objectForKey:@"users"];
  17. followersCount = [[followersDictionary objectForKey:@"total_number"] integerValue]; //粉丝总数
  18. nextCursor = [[followersDictionary objectForKey:@"next_cursor"] integerValue];  //粉丝列表
  19. for (NSDictionary *dictionary in followersArray) {
  20. User *followersUser = [[User alloc] init];
  21. [followersUser initUserWithDictionary:dictionary];
  22. [self.followersMutableArray addObject:followersUser];
  23. }
  24. });
  25. dispatch_sync(dispatch_get_main_queue(), ^{
  26. [self.tableView reloadData];
  27. [hud removeFromSuperview];
  28. });
  29. });
  30. }
  31. //处理tableview滑动到底了
  32. - (void) scrollViewDidScroll:(UIScrollView *)scrollView {
  33. CGPoint contentOffsetPoint = self.tableView.contentOffset;
  34. CGRect frame = self.tableView.frame;
  35. if (contentOffsetPoint.y == self.tableView.contentSize.height - frame.size.height)
  36. {
  37. if (nextCursor!=0) {
  38. [self loadFollersDataWithCursor:nextCursor];
  39. }
  40. //全部加载完毕
  41. else {
  42. MBProgressHUD *endHud = [[MBProgressHUD alloc] init];
  43. endHud.mode = MBProgressHUDModeText;
  44. endHud.labelText = @"提示";
  45. endHud.detailsLabelText = @"粉丝数据已全部加载!";
  46. [self.tableView addSubview:endHud];
  47. [endHud show:YES];
  48. [endHud hide:YES afterDelay:0.5];
  49. }
  50. }
  51. }

注意到其中的nextCursor这个参数,就是用来继续加载的关键参数,在开始的时候

nextCursor = 0;
[self loadFollersDataWithCursor:nextCursor];

以后每一次加载数据的时候就用获取到的新值为它重新赋值。

(2)tableview视图界面的组织

这里粉丝头像和粉丝的昵称的显示就不多说了,很简单的。代码如下:

  1. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
  2. {
  3. static NSString *CellIdentifier = @"FansCell";
  4. FansCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
  5. if (cell == nil) {
  6. cell = [[FansCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
  7. }
  8. //这里的User类就是表示一个粉丝
  9. User *aUser = [[User alloc] init];
  10. aUser = [_followersMutableArray objectAtIndex:[indexPath row]];
  11. cell.nameLabel.adjustsFontSizeToFitWidth = YES;
  12. cell.nameLabel.text = aUser.nameString;
  13. //设置按键文字
  14. cell.fansButtonLabel.titleLabel.adjustsFontSizeToFitWidth = YES;
  15. if (aUser.following) {
  16. //表示我已经关注了该粉丝
  17. [cell.fansButtonLabel setTitle:@"互相关注" forState:UIControlStateNormal];
  18. }
  19. else {
  20. [cell.fansButtonLabel setTitle:@"+关注" forState:UIControlStateNormal];
  21. }
  22. //设置头像
  23. __block NSData *imageData;
  24. dispatch_async(dispatch_get_global_queue(0, 0), ^{
  25. dispatch_sync(dispatch_get_global_queue(0, 0), ^{
  26. imageData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:aUser.profileImageURL]];
  27. });
  28. dispatch_sync(dispatch_get_main_queue(), ^{
  29. UIImage *image = [[UIImage alloc] initWithData:imageData];
  30. [cell.imageView setImage:image];
  31. });
  32. });
  33. //头像设置圆角
  34. CALayer *l = [cell.imageView layer];   //获取ImageView的层
  35. [l setMasksToBounds:YES];
  36. [l setCornerRadius:6.0];
  37. //设置粉丝的id号,这里只是为取消关注或者添加关注的请求参数用
  38. cell.fansUIDString = aUser.IDString;
  39. return cell;
  40. }

说明:

1、里面的头像我设置成圆角,这时需要#import "QuartzCore/QuartzCore.h",其他都可以看懂的吧。

2、其中获取头像的方法是:

  1. -(UIImage *) getImageFromURL:(NSString *)fileURL {
  2. UIImage * resultImage = [[UIImage alloc] init];
  3. NSData * data = [NSData dataWithContentsOfURL:[NSURL URLWithString:fileURL]];
  4. resultImage = [UIImage imageWithData:data];
  5. return resultImage;
  6. }

在这一部分的内容中要值得说明的是我添加的那个按键的处理。首先说一下我这个按键的作用:我们在获取到的粉丝JSON数据中有:follow_me和following这两个项,前者表示的是该粉丝是否关注我,显然我的粉丝肯定是关注我的啦,所以一直返回是true;后者表示的是我是否关注这个粉丝,有关注返回true,否则就返回false。所以我们就可以在这里面做点事情了。

如果我没有关注这个粉丝即following是false的话,button的作用就是可以添加对这个粉丝的关注,button的label就是“+关注”。

如果我关注了这个粉丝即following是true的话,button的作用就是可以取消对这个粉丝的关注,button的label就是“取消关注”;

由于有这部分的处理,所以我定义了一个Fanscell类专门是用于处理cell这部分的内容。

下面着重讲的是关注和取消关注粉丝的处理。

①、请求API及参数

添加关注的API:https://api.weibo.com/2/friendships/create.json

取消关注的API: https://api.weibo.com/2/friendships/destroy.json

二者调用时所需的参数除了access_token之外,还要粉丝的uid或者screen_name(二选一),注意前者是long long (int64)类型,后者是string类型,我选用的是uid这个参数。

②、Fanscell类

其中包括的有:

  1. - (IBAction)fansButton:(id)sender;
  2. @property (weak, nonatomic) IBOutlet UIButton *fansButtonLabel;
  3. @property (weak, nonatomic) IBOutlet UILabel *nameLabel;
  4. @property (weak, nonatomic) IBOutlet UIImageView *headImageView;
  5. @property (strong, nonatomic) NSString *fansUIDString;//粉丝的UID

其中的fansButton方法是用来处理关注和取消关注粉丝的。

下面先给出处理的过程代码再解说:

  1. - (IBAction)fansButton:(id)sender {
  2. destroyFriendships = NO;
  3. creatFriendships = NO;
  4. if ([self.fansButtonLabel.titleLabel.text isEqualToString:@"互相关注"]) {
  5. destroyFriendships = YES;
  6. UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:@"是否取消关注" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil];
  7. [alert show];
  8. }
  9. else if ([self.fansButtonLabel.titleLabel.text isEqualToString:@"+关注"]) {
  10. creatFriendships = YES;
  11. UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:@"是否关注" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil];
  12. [alert show];
  13. }
  14. }
  15. - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
  16. //取消关注
  17. if (destroyFriendships && buttonIndex == 1) {
  18. MBProgressHUD *custuonHUD = [[MBProgressHUD alloc]init];
  19. custuonHUD.customView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"37x-Checkmark.png"]];
  20. custuonHUD.mode = MBProgressHUDModeCustomView;
  21. [self addSubview:custuonHUD];
  22. NSURL *url = [NSURL URLWithString:FRIENDSHIPS_DESTROY];
  23. ASIFormDataRequest *item = [[ASIFormDataRequest alloc] initWithURL:url];
  24. [item setPostValue:[InfoForSina returnAccessTokenString]    forKey:@"access_token"];
  25. [item setPostValue:[NSString stringWithFormat:@"%lld",[_fansUIDString longLongValue]]  forKey:@"uid"];
  26. [item setCompletionBlock:^{
  27. [self.fansButtonLabel setTitle:@"+关注" forState:UIControlStateNormal];
  28. custuonHUD.labelText = @"取消关注成功!";
  29. [custuonHUD show:YES];
  30. [custuonHUD hide:YES afterDelay:2];
  31. }];
  32. [item setFailedBlock:^{
  33. custuonHUD.labelText = @"取消关注失败!";
  34. [custuonHUD show:YES];
  35. [custuonHUD hide:YES afterDelay:2];
  36. }];
  37. [item startAsynchronous];
  38. }
  39. //添加关注
  40. else if (creatFriendships && buttonIndex == 1) {
  41. //使用ASI这个类库处理添加关注的数据请求
  42. /*
  43. MBProgressHUD *custuonHUD = [[MBProgressHUD alloc]init];
  44. custuonHUD.customView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"37x-Checkmark.png"]];
  45. custuonHUD.mode = MBProgressHUDModeCustomView;
  46. [self addSubview:custuonHUD];
  47. NSURL *url = [NSURL URLWithString:FRIENDSHIPS_CREAT];
  48. ASIFormDataRequest *item = [[ASIFormDataRequest alloc] initWithURL:url];
  49. [item setPostValue:[InfoForSina returnAccessTokenString]    forKey:@"access_token"];
  50. [item setPostValue:[NSString stringWithFormat:@"%lld",[_fansUIDString longLongValue]]  forKey:@"uid"];
  51. [item setCompletionBlock:^{
  52. [self.fansButtonLabel setTitle:@"互相关注" forState:UIControlStateNormal];
  53. custuonHUD.labelText = @"关注成功!";
  54. [custuonHUD show:YES];
  55. [custuonHUD hide:YES afterDelay:1];
  56. }];
  57. [item setFailedBlock:^{
  58. custuonHUD.labelText = @"关注失败!";
  59. [custuonHUD show:YES];
  60. [custuonHUD hide:YES afterDelay:1];
  61. }];
  62. [item startAsynchronous];
  63. */
  64. //不使用ASI这个类库处理添加关注的数据请求
  65. NSURL *url = [NSURL URLWithString:FRIENDSHIPS_CREAT];
  66. NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:5.0];
  67. [request setHTTPMethod:@"POST"];
  68. NSString *postString = [NSString stringWithFormat:@"access_token=%@&uid=%lld",[InfoForSina returnAccessTokenString],[_fansUIDString longLongValue]];
  69. NSMutableData *postData = [[NSMutableData alloc] init];
  70. [postData appendData:[postString dataUsingEncoding:NSUTF8StringEncoding]];
  71. [request setHTTPBody:postData];
  72. self.connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];
  73. }
  74. }
  75. #pragma mark - NSURLConnection delegate Methods
  76. -(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
  77. {
  78. self.responseData = [[NSMutableData alloc] initWithLength:0];
  79. }
  80. -(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
  81. {
  82. [self.responseData appendData:data];
  83. }
  84. -(void)connectionDidFinishLoading:(NSURLConnection *)theconnection
  85. {
  86. MBProgressHUD *custuonHUD = [[MBProgressHUD alloc]init];
  87. custuonHUD.customView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"37x-Checkmark.png"]];
  88. custuonHUD.mode = MBProgressHUDModeCustomView;
  89. [self addSubview:custuonHUD];
  90. NSError *error;
  91. NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:self.responseData options:kNilOptions error:&error];
  92. NSString *idString = [dict objectForKey:@"idstr"];
  93. if(idString) {
  94. [self.fansButtonLabel setTitle:@"互相关注" forState:UIControlStateNormal];
  95. custuonHUD.labelText = @"关注成功!";
  96. [custuonHUD show:YES];
  97. [custuonHUD hide:YES afterDelay:2.3];
  98. }
  99. else {
  100. custuonHUD.labelText = @"关注失败!";
  101. [custuonHUD show:YES];
  102. [custuonHUD hide:YES afterDelay:2.3];
  103. }
  104. [self.connection cancel];
  105. }
  106. -(void)connection:(NSURLConnection *)theconnection didFailWithError:(NSError *)error
  107. {
  108. MBProgressHUD *failedHud = [[MBProgressHUD alloc] init];
  109. failedHud.mode = MBProgressHUDModeText;
  110. failedHud.labelText = @"提示";
  111. failedHud.detailsLabelText = @"发表评论失败!";
  112. [failedHud show:YES];
  113. [self addSubview:failedHud];
  114. [failedHud hide:YES afterDelay:1.3];
  115. [self.connection cancel];
  116. }

说明:

1、当按下这个button时会触发一个UIAlertView,提示是否确定关注和取消关注。

          

2、确定要关注或者取消关注粉丝的处理在UIAlertView的delegate方法中处理。

3、关注和取消关注粉丝的数据请求方式是POST,我们可以用ASIHTTPRequest来异步方式处理,也可以用不用这个类库,用系统自带的方法异步POST处理。代码中有我使用了这这两种方式。其中取消关注我是使用ASIHTTPRequest,而添加关注是使用系统自带的方法(当然注释部分也给出了ASIHTTPRequest的使用代码)。

注意,如果是使用系统自带的方式异步POST处理,我还添加了两个property:

@property (strong, nonatomic) NSURLConnection *connection;
@property (strong, nonatomic) NSMutableData *responseData;

通过代码可以清楚的看到,前一种处理方式十分简洁,后一种处理方式由于要实现delegate方法,所以感觉有点麻烦,二者孰好孰不好,自己感觉咯!

4、在数据请求结束我继续使用MBProgressHUD这个类库添加了一些提示框,表示关注是否成功或者取消关注是否成功。效果如下:

          

这个页面的处理差不多就是这样了!

ios sinaweibo 客户端(三)的更多相关文章

  1. ios sinaweibo 客户端(一)

    上一篇sina微博Demo已经完成的认证,下面就开始进入微博相关内容的加载及显示.其实主要的工作就是调用微博API 加载相关的json数据,然后进行解析,然后在界面中进行组织好在tableview中进 ...

  2. ios sinaweibo 客户端(二)

    这一篇博文讲述发微博界面的实现. 首先我们先了解一下在这个发微博界面中需要做哪些事情吧! (1) 发微博包括文字内容和微博图片,所以我们可以用一个textview来装载微博文字内容,用一个imagev ...

  3. iOS开发UI篇—iOS开发中三种简单的动画设置

    iOS开发UI篇—iOS开发中三种简单的动画设置 [在ios开发中,动画是廉价的] 一.首尾式动画 代码示例: // beginAnimations表示此后的代码要“参与到”动画中 [UIView b ...

  4. 一元云购完整源码 云购CMS系统 带安卓和ios手机客户端

    看起来不错的一套一元云购CMS源码,源码包里面带了安卓和ios手机客户端,手机客户端需要自己反编译.    这里不做功能和其它更多的介绍,可以自己下载后慢慢测试了解.    下面演示图为亲测截图< ...

  5. 2016最新一元云购完整源码 云购CMS系统 带安卓和ios手机客户端 源码免费分享

    原文转自:http://www.zccode.com/thread-724-1-1.html 该资源说明: 看起来不错的一套一元云购CMS源码,源码包里面带了安卓和ios手机客户端,手机客户端需要自己 ...

  6. XMPPFrameWork IOS 开发(三)登录

    原始地址:XMPPFrameWork IOS 开发(三) XMPP中常用对象们: XMPPStream:xmpp基础服务类 XMPPRoster:好友列表类 XMPPRosterCoreDataSto ...

  7. 在ios微信客户端遇到的坑,input等错位

    1.判断移动端设备 // 处理iOS 微信客户端弹窗状态下调起输入法后关闭输入法页面元素错位解决办法 var ua = window.navigator.userAgent.toLowerCase() ...

  8. iOS 应用架构 (三)

    iOS 客户端应用架构看似简单,但实际上要考虑的事情不少.本文作者将以系列文章的形式来回答 iOS 应用架构中的种种问题,本文是其中的第二篇,主要讲 View 层的组织和调用方案.下篇主要讨论做 Vi ...

  9. 直播时代--IOS直播客户端SDK,美颜直播【开源】

    当前视频直播非常火爆,手机端的视频直播也非常火爆,PGC.UGC的视频直播门槛都降低了很多. 本文介绍一个:IOS 客户端直播的SDK,代码完全开源. 直播时代:让IOS普通开发者一天内做出一个RTM ...

随机推荐

  1. 使用Unity容器实现属性注入

    简介 Unity :是微软用C#实现的轻量级,可扩展的依赖注入容器. 控制反转:(Inversion of Control,缩写为IoC),是用来消减程序之间的耦合问题,把程序中上层对下层依赖,转移到 ...

  2. IT兄弟连 Java语法教程 编写Java源代码

    现在我们来一步一步的编写第一个Java程序,鼎鼎大名的“HelloWorld”. 编写Java源代码 编写Java源代码可以使用任何无格式的文本编辑器,在Windows操作系统上可以使用记事本.Edi ...

  3. video,audio用法小例子

    用此小程序设计播放/暂停,放大缩小 <!DOCTYPE html> <html> <body> <div style="text-align:cen ...

  4. 笔记-JavaWeb学习之旅14

    JSTL:JavaServer Pages Tag Library JSP标准标签库 if标签 <%@ page import="java.util.ArrayList" % ...

  5. VS2015 调试出现无法启动iis express web服务器

    VS2015 调试出现无法启动iis express web服务器 在项目目录下找到.vs文件夹,然后在.vs/config/applicationhost.config找到这个配置文件,删除掉,然后 ...

  6. CodeForces - 296A-Yaroslav and Permutations(思维)

    Yaroslav has an array that consists of n integers. In one second Yaroslav can swap two neighboring a ...

  7. (转)Centos 7.3 用户和组管理

    Centos 7.3 用户和组管理 原文:http://blog.csdn.net/github_39069288/article/details/73306489 3.1 用户和密码配置文件 pas ...

  8. JS filter使用

    filter 用于筛选数组中符合条件的所以元素,filter只能接受函数 注意:filter只返回筛选结果,不会对原来数组改变 实现方法: <html lang="en"&g ...

  9. 判断网站织梦DedeCms版本的方法

    这个方法可以判断出目标网站所使用的织梦DedeCms是哪个版本的,打了哪一天的补丁. 在需要判断网站织梦版本的的URL路径后面添加/data/admin/ver.txt 如官方的:http://www ...

  10. mysql 存储过程变量及循环的使用

    1.用游标循环 BEGIN -- 定义变量 -- 定义done DECLARE done INT; -- 定义 ammeter_id_bl DECLARE ammeter_id_bl DOUBLE; ...