iOS 新浪微博客户端Demo实践之(六) 微博评论列表页面和发评论

来源:互联网 发布:java权限管理 编辑:程序博客网 时间:2024/05/01 18:37

这篇博文讲的是微博评论列表的页面和如何对微博发评论。

                     

有上面的效果视图可以知道,在微博评论视图中第一个cell是显示微博的内容,接下来的cell才是显示评论内容,评论内容的显示包括:发评论人的昵称,评论内容和评论的时间;而发评论视图就是一个简单的textview和一个评论button,这部分简单。

(1)微博评论视图

    ①获取微博评论的API是https://api.weibo.com/2/comments/show.json 它的请求的参数除了access_token和微博的id号之外,我还用到了一个参数,就是page,之前已经说过了,数据的返回是以页为单位的,这里一页返回的评论数默认就是50,当然你也可以设置这个参数count来改变每一页返回的评论数,我没有这么做。

所以一共就有三个参数。

+ (NSString *)returnCommentUrlStringWithID:(long long)weiboID page:(int)page {    NSString *urlString = [[NSString alloc] initWithFormat:@"%@?access_token=%@&id=%lld&page=%d",COMMENTS,[InfoForSina returnAccessTokenString],weiboID,page];    return urlString;}
其中的COMMENTS表示这个API。

数据的请求和解析如下:

- (void) continueLoadData:(int)page {    //GCD异步获取数据    dispatch_async(dispatch_get_global_queue(0, 0), ^{                dispatch_sync(dispatch_get_global_queue(0, 0), ^{                        hud.labelText = @"正在加载评论数据...";            [hud show:YES];            [self.view addSubview:hud];                        NSString *urlString = [InfoForSina returnCommentUrlStringWithID:_status.statusId page:page];            NSURL *url = [NSURL URLWithString:urlString];            NSURLRequest *request = [[NSURLRequest alloc]initWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy                                                     timeoutInterval:10];            NSData *commentListData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];            NSString *dataListString = [[NSString alloc] initWithData:commentListData encoding:NSUTF8StringEncoding];            NSDictionary *dataListDictionary = [dataListString objectFromJSONString];                        _totalNum = [[dataListDictionary objectForKey:@"total_number"] integerValue];                        [_commentArray addObjectsFromArray:[dataListDictionary objectForKey:@"comments"]];        });                dispatch_sync(dispatch_get_main_queue(), ^{            [self.tableView reloadData];            [hud removeFromSuperview];        });    });}

当然,假如评论数超过一页的50条的话,我们继续下来tableview的时候就应该继续加载评论内容。所以我们就要检测是否要继续加载,其中如果是评论总是不超过50和

_page > (_totalNum/50+1)的时候就不用继续数据请求了,给出一个提示框表示数据已经全部加载完毕。

//处理tableview滑动到底了- (void) scrollViewDidScroll:(UIScrollView *)scrollView {        CGPoint contentOffsetPoint = self.tableView.contentOffset;        CGRect frame = self.tableView.frame;        if (contentOffsetPoint.y == self.tableView.contentSize.height - frame.size.height)    {                if (_totalNum <= 50 ||  _i > (_totalNum/50+1) ) {            MBProgressHUD *endHud = [[MBProgressHUD alloc] init];            endHud.mode = MBProgressHUDModeText;            endHud.labelText = @"提示";            endHud.detailsLabelText = @"scroll to the end";            [self.tableView addSubview:endHud];            [endHud show:YES];            [endHud hide:YES afterDelay:1];        }        else if (_totalNum > [_commentArray count]){            [self continueLoadData:++_i];        }    }}

②tableview内容的显示

首先第一个cell是显示微博内容,那么我们可以使用segue从微博内容视图传递相应的微博内容数据到这个评论视图,然后在这个视图中再进行显示,显示的规则如微博主页一样。

评论内容的显示我们要注意的是cell高度的计算和cell重用机制可能会导致的内容重叠问题,这个没有什么难度,在前面的博文中我都有介绍过如何解决: iOS UITableViewCell重用问题 和   iOS TableViewCell 动态调整高度。

下面直接上代码:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{        // Configure the cell...    if (indexPath.row == 0) {        WeiboCell *cell = [[WeiboCell alloc] init];        [cell setupCell:_status];//显示微博内容        return cell;    }        else {        static NSString *CellIdentifier = @"detailCell";        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];        if (cell == nil) {            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];        }        if (cell != nil) {            [cell removeFromSuperview];        }        //评论数据        NSDictionary *dictionary = [_commentArray objectAtIndex:indexPath.row-1];// 获取到一个评论        NSString *timeString = [dictionary objectForKey:@"created_at"];//评论时间        NSString *commentString = [dictionary objectForKey:@"text"]; //评论内容                NSDictionary *user = [dictionary objectForKey:@"user"]; //评论用户        NSString *userName = [user objectForKey:@"screen_name"];//用户名                        //发评论的用户名称        UILabel *userNameLabel = [[UILabel alloc] initWithFrame:CGRectZero];        [userNameLabel setFont:[UIFont boldSystemFontOfSize:17.0f]];                [userNameLabel setText:userName];        userNameLabel.adjustsFontSizeToFitWidth = YES;        [userNameLabel setFrame:CGRectMake(CELL_CONTENT_MARGIN,CELL_CONTENT_MARGIN, 160,30)];        userNameLabel.tag = 100;        [[cell viewWithTag:100] removeFromSuperview];        [[cell contentView] addSubview:userNameLabel];                //设置评论发布时间        UILabel *timeLabel = [[UILabel alloc] initWithFrame:CGRectZero];        [timeLabel setFont:[UIFont systemFontOfSize:FONT_SIZE]];                [timeLabel setText:[self getTimeString:timeString]];        [timeLabel setTextAlignment:NSTextAlignmentRight];        timeLabel.adjustsFontSizeToFitWidth = YES;        [timeLabel setFrame:CGRectMake(170,CELL_CONTENT_MARGIN,140,20)];        timeLabel.tag = 101;        [[cell viewWithTag:101]removeFromSuperview];        [[cell contentView] addSubview:timeLabel];                //评论内容        UILabel *commentLabel = [[UILabel alloc] initWithFrame:CGRectZero];        [commentLabel setLineBreakMode:NSLineBreakByWordWrapping];        [commentLabel setNumberOfLines:0];        [commentLabel setFont:[UIFont systemFontOfSize:FONT_SIZE]];                        CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), MAXFLOAT);        CGSize size = [commentString sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:NSLineBreakByWordWrapping];        [commentLabel setText:commentString];                [commentLabel setFrame:CGRectMake(CELL_CONTENT_MARGIN, 30+2*CELL_CONTENT_MARGIN, CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), size.height)];        commentLabel.tag = 102;        [[cell viewWithTag:102] removeFromSuperview];        [[cell contentView] addSubview:commentLabel];                return cell;    }}


注意:

1、tableview cell 的numberOfRowsInSection:返回的应该是 1+评论数,这个1表示这条微博。

2、由于第一个cell 显示的是微博的内容,那么接下来cell的 indexPath.row 和 评论数组中每一条评论的下标就会相差1。也就是说,当indexPath.row = 2时,对于评论数组中评论的下标就是2-1=1。这一点要特别小心,否则会出现数组下标的bug。


这是cell计算高度的代码

-(CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {    if (indexPath.row == 0) {       //返回微博内容cell 的高度,微博内容高度的计算和前面微博主页tableview cell高度的计算一样。 这里为了节省篇幅就不贴代码了。    }    else {        NSDictionary *dictionary = [_commentArray objectAtIndex:indexPath.row-1];// 获取到一个评论  特别要主页这类的数组下标要-1        NSString *commentString = [dictionary objectForKey:@"text"]; //评论内容                CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), MAXFLOAT);        CGSize size = [commentString sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:NSLineBreakByWordWrapping];        return 30+3*CELL_CONTENT_MARGIN+size.height;    }    }


(2)发评论的处理

我们在navigation bar 的右边设置了一个评论按键。使用segue方式连接到发评论视图,这样的好处就是可以传递微博的id号。

-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {        if ([segue.identifier isEqualToString:@"commentSegue"]) {        CommentCreatViewController *vc = [segue destinationViewController];        vc.weiboID = _status.statusId;    }}

发评论所用到的API是https://api.weibo.com/2/comments/create.json其中需要的参数包括access_token,comment(评论内容必须做URLencode,而且字数一定要在0到140之间)和微博的id。HTTP请求方式为POST。

这里可以用ASIHTTPRequest这个第三方类库来处理,也可以用系统自带的方法处理异步的POST。

下面给出我的代码:

- (IBAction)commentButton:(id)sender {        [_commentTextView resignFirstResponder];            NSString *content = [[NSString alloc] initWithString:_commentTextView.text];    //计算发送微博的内容字数,并作相应的处理    NSInteger contentLength = content.length;    if (contentLength > 140) {        MBProgressHUD *overLengthHud = [[MBProgressHUD alloc] initWithView:self.view];        [self.view addSubview:overLengthHud];        overLengthHud.mode = MBProgressHUDModeText;        overLengthHud.labelText = @"提示信息";        overLengthHud.detailsLabelText = [NSString stringWithFormat:@"微博字数:%d 超过140上限!",contentLength];        [overLengthHud show:YES];        [overLengthHud hide:YES afterDelay:2];    }    else if(contentLength == 0) {        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:@"请输入评论内容!" delegate:nil cancelButtonTitle:@"好" otherButtonTitles:nil, nil];        [alert show];    }    else {        _hud = [[MBProgressHUD alloc] init];        _hud.dimBackground = YES;        _hud.labelText = @"正在发送...";        [_hud show:YES];        [self.view addSubview:_hud];            NSString *accessTokenString = [[NSUserDefaults standardUserDefaults] objectForKey:@"access_token"];        NSString *paramString = [NSString stringWithFormat:@"comment=%@&id=%lld&access_token=%@",content,_weiboID,accessTokenString];                NSMutableData *postCommentData = [[NSMutableData alloc] init];        [postCommentData appendData:[paramString dataUsingEncoding:NSUTF8StringEncoding]];        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:COMMENTCREAT] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:5.0];        [request setHTTPMethod:@"POST"];        [request setHTTPBody:postCommentData];                self.connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];    }}#pragma mark - NSURLConnection delegate Methods-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{    self.responseData = [[NSMutableData alloc] initWithLength:0];}-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{    [self.responseData appendData:data];}-(void)connectionDidFinishLoading:(NSURLConnection *)theconnection{        [_hud removeFromSuperview];    NSError *error;    NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:self.responseData options:kNilOptions error:&error];        NSString *textString = [dict objectForKey:@"text"];    if(textString)    {        MBProgressHUD *successHud = [[MBProgressHUD alloc] init];        successHud.mode = MBProgressHUDModeText;        successHud.labelText = @"提示";        successHud.detailsLabelText = @"发表评论成功!";        [successHud show:YES];        [self.view addSubview:successHud];        [successHud hide:YES afterDelay:1.3];    }    else {        MBProgressHUD *successHud = [[MBProgressHUD alloc] init];        successHud.mode = MBProgressHUDModeText;        successHud.labelText = @"提示";        successHud.detailsLabelText = @"发表评论失败!";        [successHud show:YES];        [self.view addSubview:successHud];        [successHud hide:YES afterDelay:1.3];           }        [self.connection cancel];}-(void)connection:(NSURLConnection *)theconnection didFailWithError:(NSError *)error{    MBProgressHUD *successHud = [[MBProgressHUD alloc] init];    successHud.mode = MBProgressHUDModeText;    successHud.labelText = @"提示";    successHud.detailsLabelText = @"发表评论失败!";    [successHud show:YES];    [self.view addSubview:successHud];    [successHud hide:YES afterDelay:1.3];    [self.connection cancel];}


代码简单,不需要解释了。

好了这一部分的介绍就到此结束了!微笑







原创粉丝点击