iOS IM即时通信之聊天界面UI框架

xxx853200 8年前
   <h3>效果:</h3>    <p style="text-align:center"><img src="https://simg.open-open.com/show/e47e604a31f78b29e502515c282440af.gif"></p>    <p style="text-align:center">聊天效果.gif</p>    <h3>随便扯扯</h3>    <p>公司项目以前就集成环信, 后来不知道什么原因给撤了, 最近又不知道打什么鸡血要上IM, 界面一个礼拜搭建完成, 前前后后两个月一直在改pm, 改接口, 一把心酸一把泪, 由于后台拖拖拖, 产品改改改, 我的小儿子终于在前两个礼拜上线啦~(≧▽≦)/~啦啦啦,<br> 最近闲的蛋疼, 决定把我的小儿子抽出来给大家玩玩, 里面也借鉴了很多优秀的代码, 喜欢的可以参考(写的比较简单, 勿喷~)</p>    <p>项目结构</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/811f29f66bb078f88ce8df284d2bcbdd.png"></p>    <p style="text-align:center">项目结构.png</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/9f5fa63f76d3f7cc9b074506f6a429bc.png"></p>    <p style="text-align:center">项目结构.png</p>    <p>表情键盘</p>    <ul>     <li>如何更改? 在下面的代码修改plist文件, 替换表情图片</li>    </ul>    <pre>  <code class="language-objectivec">+ (NSArray *)loadPackages {      if (_packages) {          return _packages;      }        NSMutableArray *models = [NSMutableArray array];      KeyboardEmojiPackage *packge = [[KeyboardEmojiPackage alloc] init];        NSString *path = [[NSBundle mainBundle] pathForResource:@"emoticons.plist" ofType:nil];      NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];      NSArray *array = dict[@"packages"];        for (NSDictionary *dict in array) {          KeyboardEmojiPackage *package = [[KeyboardEmojiPackage alloc] initWithDict:dict];          [packge loadEmojis];          [packge appendEmptyEmoji];          [models addObject:package];      }        _packages = models;      return models;  }      /**   *  加载当前组所有的表情   */  - (void)loadEmojis {        NSString *path = [[NSBundle mainBundle] pathForResource:self.group_name ofType:nil];        NSArray *array = [NSArray arrayWithContentsOfFile:path];        NSMutableArray *models = [NSMutableArray array];        NSInteger index = 0;        for (NSDictionary *dict in array) {          KeyboardEmojiModel *emotion = [[KeyboardEmojiModel alloc] initWithDict:dict];          emotion.group_folder_name = self.group_folder_name;          [models addObject:emotion];          index ++;      }        self.emojis = models;  }</code></pre>    <ul>     <li>修改布局      <ul>       <li>根据需要修改3 X 7 或 2 X 4</li>      </ul> </li>    </ul>    <pre>  <code class="language-objectivec">- (void)prepareLayout {      CGFloat itemWith = [UIScreen mainScreen].bounds.size.width / 4;      CGFloat itemHeight = 55;      self.itemSize = CGSizeMake(itemWith, itemHeight);      self.minimumLineSpacing = 0;      self.minimumInteritemSpacing = 0;      self.scrollDirection = UICollectionViewScrollDirectionHorizontal;        self.collectionView.pagingEnabled = YES;      self.collectionView.showsVerticalScrollIndicator = NO;      self.collectionView.showsHorizontalScrollIndicator = NO;  //    self.collectionView.bounces = NO;        // 让cell居中显示      CGFloat offsetY = (self.collectionView.bounds.size.height - (2 * itemHeight)) * 0.48;      self.collectionView.contentInset = UIEdgeInsetsMake(offsetY, 0, 0, offsetY);  }</code></pre>    <ul>     <li> <p>聊天气泡</p> <p>聊天气泡用的是图片, 用户可自定义更换</p> </li>    </ul>    <pre>  <code class="language-objectivec">// bubbleView 的背景图片  NSString *const BUBBLE_LEFT_IMAGE_NAME = @"IM_Chat_receiver_bg";  NSString *const BUBBLE_RIGHT_IMAGE_NAME = @"IM_Chat_sender_bg";</code></pre>    <p>说一下输入框的问题</p>    <p>输入框用的是textView, 在输入框换行改变高度到第二行的时候, 文字会向上偏移, 到第三行又正常, 回退也是正常的, 这个问题纠结的很久, 也查了很多资料, 如果有朋友遇到这个问题可以借鉴下面的代码</p>    <pre>  <code class="language-objectivec">#pragma mark - UITextViewDelegate  - (void)textViewDidChange:(UITextView *)textView {        static CGFloat maxHeight = 80.0f;      CGRect frame = textView.frame;      CGSize constraintSize = CGSizeMake(frame.size.width, MAXFLOAT);      CGSize size = [textView sizeThatFits:constraintSize];      if (size.height >= maxHeight) {          size.height = maxHeight;          textView.scrollEnabled = YES;   // 允许滚动          [textView scrollRectToVisible:CGRectMake(0, textView.contentSize.height-7.5, textView.contentSize.width, 10) animated:NO];      } else {          textView.scrollEnabled = NO;    // 不允许滚动,当textview的大小足以容纳它的text的时候,需要设置scrollEnabed为NO,否则会出现光标乱滚动的情况      }        [UIView animateWithDuration:_animationDuration delay:0 options:(_animationCurve << 16 | UIViewAnimationOptionBeginFromCurrentState) animations:^{          // 调整整个InputToolBar 的高度          self.height = (15 + size.height) - kChatBarHeight < 5 ? kChatBarHeight : 15 + size.height;          CGFloat keyboardHeight = _keyboardHeight;          if (self.moreBtn.selected) {              keyboardHeight = kChatMoreHeight;          }          else if (self.emojiBtn.selected) {              keyboardHeight = kChatEmojiHeight;          }            self.y = SCREEN_H - self.height - keyboardHeight;          _tableView.height = self.y - kNavBarHeight;          [self layoutIfNeeded];      } completion:nil];  }</code></pre>    <h3>第三方开源框架</h3>    <p>FMDB --> 对SQLite的API进行了封装</p>    <p>SDWebImage --> 缓存下载图片</p>    <p>TZImagePickerController --> 一个支持多选、选原图和视频的图片选择器,同时有预览、裁剪功能</p>    <p>YYKit --> 是一组庞大、功能丰富的 iOS 组件</p>    <h3>写在最后</h3>    <p>整个消息UI还是仿照环信的, 基本上大致相同, 只是稍加修改, 因为需求只需要聊天, 文字, 表情, 所以demo也只有这些, 基本比较简单, 如果觉得本文对你有帮助,感谢给个star</p>    <p> </p>    <p> </p>