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

效果:

聊天效果.gif

隨便扯扯

公司項目以前就集成環(huán)信, 后來不知道什么原因給撤了, 最近又不知道打什么雞血要上IM, 界面一個禮拜搭建完成, 前前后后兩個月一直在改pm, 改接口, 一把心酸一把淚, 由于后臺拖拖拖, 產(chǎn)品改改改, 我的小兒子終于在前兩個禮拜上線啦(≧≦)/啦啦啦,
最近閑的蛋疼, 決定把我的小兒子抽出來給大家玩玩, 里面也借鑒了很多優(yōu)秀的代碼, 喜歡的可以參考(寫的比較簡單, 勿噴~)

項目結(jié)構(gòu)


項目結(jié)構(gòu).png
項目結(jié)構(gòu).png

表情鍵盤

  • 如何更改? 在下面的代碼修改plist文件, 替換表情圖片
+ (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;
}
  • 修改布局
    • 根據(jù)需要修改3 X 7 或 2 X 4
- (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);
}
  • 聊天氣泡

    聊天氣泡用的是圖片, 用戶可自定義更換

// bubbleView 的背景圖片
NSString *const BUBBLE_LEFT_IMAGE_NAME = @"IM_Chat_receiver_bg";
NSString *const BUBBLE_RIGHT_IMAGE_NAME = @"IM_Chat_sender_bg";

說一下輸入框的問題

輸入框用的是textView, 在輸入框換行改變高度到第二行的時候, 文字會向上偏移, 到第三行又正常, 回退也是正常的, 這個問題糾結(jié)的很久, 也查了很多資料, 如果有朋友遇到這個問題可以借鑒下面的代碼

#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的時候挺物,需要設(shè)置scrollEnabed為NO杯矩,否則會出現(xiàn)光標亂滾動的情況
   }

   [UIView animateWithDuration:_animationDuration delay:0 options:(_animationCurve << 16 | UIViewAnimationOptionBeginFromCurrentState) animations:^{
       // 調(diào)整整個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];
}

第三方開源框架

FMDB --> 對SQLite的API進行了封裝
SDWebImage --> 緩存下載圖片
TZImagePickerController --> 一個支持多選敞贡、選原圖和視頻的圖片選擇器,同時有預覽轴脐、裁剪功能
YYKit --> 是一組龐大障陶、功能豐富的 iOS 組件

寫在最后

整個消息UI還是仿照環(huán)信的, 基本上大致相同, 只是稍加修改, 因為需求只需要聊天, 文字, 表情, 所以demo也只有這些, 基本比較簡單, 如果覺得本文對你有幫助莉兰,感謝給個star
github地址:LHChat

補充一下

聊天cell里面也能顯示動圖,但是發(fā)送大量動態(tài)表情的時候倔喂,滑動是會卡頓铝条,用yylabel開啟異步繪制還是一樣,研究了挺久的席噩,也琢磨不出來什么班缰,有知道的大神還望在留言區(qū)指點一下,給個思路也行悼枢,謝謝(????)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末埠忘,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子馒索,更是在濱河造成了極大的恐慌莹妒,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,185評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件绰上,死亡現(xiàn)場離奇詭異旨怠,居然都是意外死亡,警方通過查閱死者的電腦和手機蜈块,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,445評論 3 385
  • 文/潘曉璐 我一進店門鉴腻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來迷扇,“玉大人,你說我怎么就攤上這事爽哎∧彼螅” “怎么了?”我有些...
    開封第一講書人閱讀 157,684評論 0 348
  • 文/不壞的土叔 我叫張陵倦青,是天一觀的道長瓮床。 經(jīng)常有香客問我,道長产镐,這世上最難降的妖魔是什么隘庄? 我笑而不...
    開封第一講書人閱讀 56,564評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮癣亚,結(jié)果婚禮上丑掺,老公的妹妹穿的比我還像新娘。我一直安慰自己述雾,他們只是感情好街州,可當我...
    茶點故事閱讀 65,681評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著玻孟,像睡著了一般唆缴。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上黍翎,一...
    開封第一講書人閱讀 49,874評論 1 290
  • 那天面徽,我揣著相機與錄音,去河邊找鬼匣掸。 笑死趟紊,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的碰酝。 我是一名探鬼主播霎匈,決...
    沈念sama閱讀 39,025評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼送爸!你這毒婦竟也來了铛嘱?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,761評論 0 268
  • 序言:老撾萬榮一對情侶失蹤碱璃,失蹤者是張志新(化名)和其女友劉穎弄痹,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體嵌器,經(jīng)...
    沈念sama閱讀 44,217評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡肛真,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,545評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了爽航。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蚓让。...
    茶點故事閱讀 38,694評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡乾忱,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出历极,到底是詐尸還是另有隱情窄瘟,我是刑警寧澤,帶...
    沈念sama閱讀 34,351評論 4 332
  • 正文 年R本政府宣布趟卸,位于F島的核電站蹄葱,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏锄列。R本人自食惡果不足惜图云,卻給世界環(huán)境...
    茶點故事閱讀 39,988評論 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望邻邮。 院中可真熱鬧竣况,春花似錦、人聲如沸筒严。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,778評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽鸭蛙。三九已至摹恨,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間规惰,已是汗流浹背睬塌。 一陣腳步聲響...
    開封第一講書人閱讀 32,007評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留歇万,地道東北人。 一個月前我還...
    沈念sama閱讀 46,427評論 2 360
  • 正文 我出身青樓勋陪,卻偏偏與公主長得像贪磺,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子诅愚,可洞房花燭夜當晚...
    茶點故事閱讀 43,580評論 2 349

推薦閱讀更多精彩內(nèi)容

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫寒锚、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,066評論 4 62
  • 一违孝、討論范圍:BTG&BCD BTC的幾個兒子:BCH刹前、BTG、BCD誕生以后雌桑,發(fā)生了一些有趣的值得研究的現(xiàn)象喇喉。 ...
    fantasyrex3閱讀 1,091評論 1 0
  • 都說,什么年齡就做你那個年齡段的事情校坑? 十八歲的時候拣技,那就好好讀書千诬;二十五歲的時候就好好工作,遇到對的人就好好的戀...
    獨孤因果閱讀 777評論 0 2
  • 止水: 見字如晤,勿念莫辨。 那日你約我去畫船上喝曼特寧傲茄,我失約了。并非我故意沮榜,是因為你的邀約公布于世盘榨,卻唯獨沒有塞進...
    梅涼閱讀 1,786評論 81 56
  • 賽場上,長跑運動員不會一開始就極速沖刺敞映,耗盡體力较曼,而是開始用中速控制體力,找到一個最佳節(jié)奏振愿,最后高速捷犹,讓體力潛能發(fā)...
    c與php閱讀 1,490評論 0 1