美文网首页demoUI进价tableview&&
iOS 实现优酷视频的评论回复功能

iOS 实现优酷视频的评论回复功能

作者: CoderMikeHe | 来源:发表于2017-03-02 10:14 被阅读3447次
    一、概述

    通过学习前面笔者提供的两种方法来实现类似微信朋友圈的评论回复功能后,首先,笔者来分析两者两者的优缺点,以及两者的使用场景。其次,笔者将通过方式一即用段头+Cell+段尾 的方法来实战优酷视频的评论回复功能,主要分析里面的业务逻辑数据处理以及细节处理。最后,希望能为广大开发者提供一点思路,少走一些弯路,填补一些细坑。

    • 方式一:使用段头+Cell+段尾推荐使用

      • 优点:评论回复cell(MHCommentCell)发挥出了UITableViewCell的重用机制;评论回复cell(MHCommentCell)的事件传递相比方式二少了一层嵌套;ModelFrame的计算针对性强。
      • 缺点:要实现tableView代理的- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section以及- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section方法,以及设置对应的高度,代码上略微繁琐。
      • 使用场景:支持无限评论回复的情况下。
    • 方式二:使用UITableViewCell嵌套UITableView

      • 优点:控制器的代码相比方式一的简单。
      • 缺点:外层的UITableView发挥了重用机制,但是Cell嵌套的UITableView未发挥重用机制,如果有1000条评论回复,那么嵌套的UITableViewCell(MHCommentCell)就得创建1000次,相当不合理,性能不好;ModelFrame的计算稍微复杂,实现的计算好内层嵌套的tableView的尺寸;评论回复cell(MHCommentCell)的事件传递,存在两层代理嵌套。
      • 使用场景:显示评论回复有限的情况下。
    • 传送门

    二、效果图
    youkuComment.gif
    三、页面分析
    1. 效果图
    MHYouKuControllers.jpg
    1. 图中字符对应的Controller
      A:MHYouKuController
      B:MHYouKuTopicController (红色框区域)
      C:MHYouKuTopicDetailController
      D:MHYouKuCommentController
      注意:文章统一用字符代替对应的Controller,怪我懒,望体谅。

    2. 评论面板(MHYouKuInputPanelView

    MHYouKuInputPanelView@2x.png
    四、需求分析
    1. A控制器和B控制器的的评论数据来源问题。
      首先,A控制器和B控制器存在父子关系,即:[A addChildViewController:B] ,具体使用细节请参考文末的Demo链接。其次,A控制器里面的tableView无法支持下拉刷新上拉加载功能,B控制器里面的tableView支持的,这种需求在视频类App非常常见,A控制器只是显示部分评论数据,点击评论数按钮跳转到B控制器来显示更多评论数据数据。终上所述,笔者采取的是在B控制器里面一旦下拉刷新获取数据后,通过代理或者通知,将评论数据回调给A控制器处理即可(PS:笔者在此采用的通知:MHCommentRequestDataSuccessNotification)。

      数据来源@2x.png
    2. 评论Cell显示查看全部xx条回复的实现问题。
      笔者这里采取了一种巧妙的方式,配置一个前端事先制定的MHComment即可。详细配置如下

      /** topic --- topicFrame */
      - (MHTopicFrame *)_topicFrameWithTopic:(MHTopic *)topic
      {
          // 这里要判断评论个数大于2 显示全部评论数
          if (topic.commentsCount>2) {
          // 设置假数据
          MHComment *comment = [[MHComment alloc] init];
          // MHAllCommentsId是前端设定的
          comment.commentId = MHAllCommentsId;
          comment.text = [NSString stringWithFormat:@"查看全部%zd条回复" , topic.commentsCount];
          // 添加假数据
          [topic.comments addObject:comment];
      }
      
          MHTopicFrame *topicFrame = [[MHTopicFrame alloc] init];
          // 传递话题模型数据,计算所有子控件的frame
          topicFrame.topic = topic;
          return topicFrame;
      }
      
    3. D控制器对视频,评论成功后,A控制器和B控制器的数据同步问题(即:两者在评论数据上保持一致,从而保证在界面上显示一致)。
      点击A控制器和B控制器的评论框,即可跳转到D控制器,即D控制器是一对多的关系。若D控制器对视频评论成功后,笔者通过通知(通知名字:MHCommentSuccessNotification)的方式,来告知AB控制器作相应的操作即可。

      视频评论@2x.png
    4. 若对AB以及C控制器里面的某个视频评论进行回复或者针对某条视频评论的回复进行评论,如何保证A控制器和B控制器的数据同步问题(即:两者在评论数据上保持一致,从而保证在界面上显示一致)。
      关键:AB以及C控制器持有的是同一个模型(MHTopicFrame),这样我们无论对数据做了任何操作,只要监听到改变时,刷新数据源方法即可。

      评论Or回复@2x.png
    5. 视频评论和回复成功后的数据处理问题。
      由于查看全部xx条回复是前端自己配置,伴随着视频的评论Or回复成功后,数据需要做相应的判断(MHYouKuInputPanelViewDelegate)。

      - (void) inputPanelView:(MHYouKuInputPanelView *)inputPanelView attributedText:(NSString *)attributedText
      {
           // 发送评论 模拟网络发送
          dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(.25f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
              // 评论或者回复成功
              MHComment *comment = [[MHComment alloc] init];
              comment.mediabase_id = self.mediabase_id;
              comment.commentId = [NSString stringWithFormat:@"%zd",[NSObject mh_randomNumber:0 to:100]];
              comment.text = attributedText;
              comment.creatTime = [NSDate mh_currentTimestamp];
          
              MHUser *fromUser = [[MHUser alloc] init];
              fromUser.userId = [AppDelegate sharedDelegate].account.userId ;
              fromUser.avatarUrl = [AppDelegate sharedDelegate].account.avatarUrl;
              fromUser.nickname = [AppDelegate sharedDelegate].account.nickname;
              comment.fromUser = fromUser;
              // 只有回复  toUser 有值
              if (inputPanelView.commentReply.isReply) {
                  MHUser *toUser = [[MHUser alloc] init];
                  toUser.avatarUrl = inputPanelView.commentReply.user.avatarUrl;
                  toUser.userId = inputPanelView.commentReply.user.userId;
                  toUser.nickname = inputPanelView.commentReply.user.nickname;
                  comment.toUser = toUser;
              }
              // 这里需要插入假数据 提高用户的体验度
              MHCommentFrame* newCommentFrame = [[MHTopicManager sharedManager] commentFramesWithComments:@[comment]].lastObject;
              // 这里要插入话题数据源中去
              // 修改评论回复数目
              self.selectedTopicFrame.topic.commentsCount  =  self.selectedTopicFrame.topic.commentsCount + 1;
              // 判断数据
              if (self.selectedTopicFrame.topic.comments.count>2) 
                  // 有查看全部xx条回复 
                  // 插入数据
                  NSInteger count = self.selectedTopicFrame.commentFrames.count;
                  NSInteger index = count - 1;
                  [self.selectedTopicFrame.commentFrames insertObject:newCommentFrame atIndex:index];
                  [self.selectedTopicFrame.topic.comments insertObject:comment atIndex:index];
      
                  // 取出最后一条数据 就是查看全部xx条回复 修改为xx+1条即可
                  MHComment *lastComment = self.selectedTopicFrame.topic.comments.lastObject;
                  lastComment.text = [NSString stringWithFormat:@"查看全部%zd条回复" , self.selectedTopicFrame.topic.commentsCount];
               }else if (self.selectedTopicFrame.topic.comments.count == 2) {
                      // 添加数据源
                      [self.selectedTopicFrame.commentFrames addObject:newCommentFrame];
                      [self.selectedTopicFrame.topic.comments addObject:comment];
                  
                      // 设置假数据
                      MHComment *lastComment = [[MHComment alloc] init];
                      lastComment.commentId = MHAllCommentsId;
                      lastComment.text = [NSString stringWithFormat:@"查看全部%zd条回复" , self.selectedTopicFrame.topic.commentsCount];
                      MHCommentFrame *lastCommentFrame =  [[MHTopicManager sharedManager] commentFramesWithComments:@[lastComment]].lastObject;
                      // 添加假数据
                      [self.selectedTopicFrame.commentFrames addObject:lastCommentFrame];
                      [self.selectedTopicFrame.topic.comments addObject:lastComment];
                  }else{
                      // <2的情况 直接添加即可 
                      // 添加数据源
                      [self.selectedTopicFrame.commentFrames addObject:newCommentFrame];
                      [self.selectedTopicFrame.topic.comments addObject:comment];
                  }
              // 发送评论回复成功的通知
              [MHNotificationCenter postNotificationName:MHCommentReplySuccessNotification object:nil userInfo:@{MHCommentReplySuccessKey:self.selectedTopicFrame}]; 
          };
      }
      
    五、期待
    1. 文章若对您有点帮助,请给个喜欢❤️,毕竟码字不易;若对您没啥帮助,请给点建议💗,切记学无止境。
    2. 针对文章所述内容,阅读期间任何疑问;请在文章底部评论指出,我会火速解决和修正问题。
    3. GitHub地址:https://github.com/CoderMikeHe
    六、代码

    MHDevelopExample_Objective_C - MHYouKuController.h/m

    相关文章

      网友评论

      • 我是派蒙:demo 里面没有 仿优酷评论�这个 例子啊
        CoderMikeHe:@zglover Github Readme.md上面写了如何使用的。
        我是派蒙:靠 GitHub拉下来的项目不完整
      • Xavier_Lost:我的模型和你完全不一致(话题数组包含字典,字典包含二级评论模型和其他话题属性),是否我自己需要包装下:frowning:
        CoderMikeHe:@略_0727 嗯嗯,是跟tableView的本身有关系,这个好像是iOS8出来了个预算高度有关系,导致这contentSize有点问题。
        Xavier_Lost:@CoderMikeHe 那我只能自己包装了,不然高度的回复的时候没有值,还有个问题就是(新闻评论案列)底部评论tableView KVO 监听contentSize不准确,导致我想跳转到评论的组时有点偏差,但是只要跳转过一次,下次就正常,不知道是不是和tableView本身有关系,期待回复:joy:
        CoderMikeHe:@略_0727 主要还是看使用场景吧,首先可以明确的理解为:一条话题,会有很多评论,所以你看看是否需要在话题模型里面新建一个属性来存放这一堆评论数据咯。
      • yeshenlong520:从头到尾的看 居然看完了 看懂了 其实说实话 代码还是蛮规范的 只是没有抽离的一目了然而已 优酷的实现 本就这么多逻辑 只是数据处理有点不好懂 其实中心思想应该是监听通知 刷新UI 把各种刷新控件和监听做好就对了 群主技术牛哦
        CoderMikeHe:@yeshenlong520 嗯嗯,之前写的比较粗糙,还望见谅
      • 飞不飞_52d6:群主,文件缺失,打不开
        CoderMikeHe:@飞不飞_52d6 运行不会报错的,尽管运行即可。
      • Zzc皮卡丘:大牛,你的项目下载下来怎么没有pods文件,pod repo update或pod install毫无作用 ???
        CoderMikeHe:@不够果断是种癌 那你就下载那个百度云那个链接,有时间在找找为什么Pod不了
        不够果断是种癌:@CoderMikeHe 我也遇到这个问题了 运行不了,并且我这边是最新的pod
        CoderMikeHe:@zzczzc123 我刚试了,没问题呀。
      • DK_Kevin:这代码风格,也就也就楼主可以看了。还有文件缺失
        CoderMikeHe:@DK_Kevin 这个之前写的有点草率,有时间再迭代一下
      • 86ad34804bc8:您好,请问有swift版本的吗?
        不够果断是种癌:@的的的的的的的的的的的的的 建议学习OC,OC在很多方面还是相当不错的,至少的懂。
        86ad34804bc8:@CoderMikeHe 没有接触过OC,直接自学的swift。嗯。我自己摸索摸索。。
        CoderMikeHe:@的的的的的的的 暂时没,应该可以根据 OC的思路 用Swift来实现的吧
      • 0da090ef6abe:demo打不开
      • 没有名字就是我的名字:欢迎各路大神没事来这群里面吹吹技术的牛逼 聊聊技术的问题,超过100人改为付费群,且行且珍惜号:614194935
        PGOne爱吃饺子:好的 谢谢作者
        CoderMikeHe:@PGOne爱吃饺子 笔者我可没有创建任何群哦。还请核查啊。
        PGOne爱吃饺子:现在进群还付费么?
      • 1c31209da44f:这代码写的。。估计只有楼主自己能看懂。。
        CoderMikeHe:@KM赵 FDT是什么?
        KuKuMan:楼主能写写FDT的吗,觉得FDT用的人还多 start也会很多哦 :joy:
        CoderMikeHe:@时间在流逝_342f :joy: 只是之前需求是这样的。一步一步迭代过来的。希望可以看看前两篇文章。对你有所帮助。
      • 夜丶火雨_d743:路过....学习下
        七声颤抖:先推荐下我自己建立的一个ios学习群515268413,欢迎在学ios编程的初学者和进阶者进群,另外群文件会每天分享最新学习视频资源给大家学习。
      • 死神一护:不知道能否添加上点赞功能
        CoderMikeHe:@死神一护 点赞功能,其实Demo里面已经做了,你可以看看里面的实现过程。我这里用的是通知,因为A、B、C控制器都有点赞这个功能,点赞成功后,三个界面需要同时修改UI。文章有用的话,请给个喜欢❤️。
      • beb57d443acc:溜溜溜

      本文标题:iOS 实现优酷视频的评论回复功能

      本文链接:https://www.haomeiwen.com/subject/mttcgttx.html