iOS 環(huán)信自定義cell

環(huán)信3.x自定義表情實(shí)現(xiàn)https://www.tuicool.com/articles/YVrmY33

很久沒有寫簡書了,首先給張效果圖,有自定義的cell,有cell的點(diǎn)擊事件,有自定義的chatBarMoreView:

推薦的做法
WechatIMG1.jpeg

//先注冊
    [self.tableView registerNib:[UINib nibWithNibName:@"ClubRoomChatNoticeCell" bundle:nil] forCellReuseIdentifier:@"ClubRoomChatNoticeCell"];

- (UITableViewCell *)messageViewController:(UITableView *)tableView cellForMessageModel:(id<IMessageModel>)model
{
    if ([[model.message.ext objectForKey:@"type"] isEqualToString:@"announced"]) {
        ClubChatOpenPrizeCell *cell = (ClubChatOpenPrizeCell *)[tableView dequeueReusableCellWithIdentifier:@"ClubChatOpenPrizeCell"];
        cell.title.text = [NSString stringWithFormat:@"%@",model.text];
        return cell;
    }
     return nil;
}

以下這種做法不推薦

D207671342CDCCAD9A187B411A7FC99A.png

我的思路是直接修改源碼的(如果不修改源碼能實(shí)現(xiàn)最好)大家可以借鑒處理的過程及思路右核,如有不妥之處,請大家及時(shí)留言告知

環(huán)信初始化

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.

    EMOptions *options = [EMOptions optionsWithAppkey:@"Xxxxxx"];
    options.enableConsoleLog = NO;
    [[EMClient sharedClient] initializeSDKWithOptions:options];
    //監(jiān)聽自動登錄的狀態(tài)
    [[EMClient sharedClient] addDelegate:self delegateQueue:nil];
    [[EMClient sharedClient].chatManager addDelegate:self delegateQueue:nil];

    return YES;
}

- (void)didConnectionStateChanged:(EMConnectionState)aConnectionState{
    if (aConnectionState == EMConnectionConnected) {
        NSLog(@"網(wǎng)絡(luò)連接成功");
    }else{
        NSLog(@"網(wǎng)絡(luò)斷開");
        //監(jiān)聽網(wǎng)絡(luò)狀態(tài)(這里通知的目地是檢測到如果沒網(wǎng)絡(luò)的情況下渺绒,修改Navigation.title的值)
    }
}

- (void)connectionStateDidChange:(EMConnectionState)aConnectionState{
    NSLog(@"斷線重連不需要其他操作%u",aConnectionState);
}

- (void)userAccountDidLoginFromOtherDevice{
    NSLog(@"在別的設(shè)備上登陸了");
}

- (void)autoLoginDidCompleteWithError:(EMError *)aError{
    NSLog(@"自動登錄完成時(shí)的回調(diào)");
}

- (void)messagesDidReceive:(NSArray *)aMessages{
    NSLog(@"收到一條新的消息");
      for (EMMessage *message in aMessages) {
          NSLog(@"%@",message);
      }
}

創(chuàng)建單聊頁面,主要是發(fā)送擴(kuò)展消息,

//
//  SingleChatViewController.m
//  TextChat
//
//  Created by apple on 2017/10/18.
//  Copyright ? 2017年 劉龍飛. All rights reserved.
//

#import "SingleChatViewController.h"

@interface SingleChatViewController ()<EaseChatBarMoreViewDelegate,EaseMessageViewControllerDelegate,EaseMessageViewControllerDataSource,EaseMessageCellDelegate>

@end

@implementation SingleChatViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    self.delegate = self;
    self.dataSource = self;
    self.chatBarMoreView.delegate = self;
    self.showRefreshHeader = YES;
    
    //去掉多余的按鈕
    [self.chatBarMoreView removeItematIndex:0];
    [self.chatBarMoreView removeItematIndex:0];
    [self.chatBarMoreView removeItematIndex:0];
    [self.chatBarMoreView removeItematIndex:0];
    [self.chatBarMoreView removeItematIndex:0];

    //自定義按鈕
    [self.chatBarMoreView insertItemWithImage:[UIImage imageNamed:@"wwww"] highlightedImage:[UIImage imageNamed:@"wwwwl"] title:@"就"];
    [self.chatBarMoreView insertItemWithImage:[UIImage imageNamed:@"wwww"] highlightedImage:[UIImage imageNamed:@"wwww"] title:@"這樣"];
    [self.chatBarMoreView insertItemWithImage:[UIImage imageNamed:@"wwww"] highlightedImage:[UIImage imageNamed:@"wwww"] title:@"被你"];
    [self.chatBarMoreView insertItemWithImage:[UIImage imageNamed:@"wwww"] highlightedImage:[UIImage imageNamed:@"wwww"] title:@"征服"];

    self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:(UIBarButtonSystemItemAdd) target:self action:@selector(touchRightButton)];
}

#pragma mark - EaseChatBarMoreViewDelegate

- (void)moreView:(EaseChatBarMoreView *)moreView didItemInMoreViewAtIndex:(NSInteger)index{
    NSLog(@"點(diǎn)擊自定義按鈕----%ld",(long)index);
}

#pragma mark - EaseMessageViewControllerDataSource

///消息顯示用戶昵稱和頭像宗兼。
//- (id<IMessageModel>)messageViewController:(EaseMessageViewController *)viewController
//                           modelForMessage:(EMMessage *)message{
//    id<IMessageModel> model = nil;
//    model = [[EaseMessageModel alloc] initWithMessage:message];
//    model.avatarImage = [UIImage imageNamed:@"EaseUIResource.bundle/user"];//默認(rèn)頭像
//    model.nickname = @"";//用戶昵稱
//    if (message.direction == EMMessageDirectionSend) {
//        NSString *headImg = [NSString stringWithFormat:@"%@%@",FILE_PATH,[ToolsManager loginUser].headImage];
//        model.avatarURLPath = headImg;
//    }
//    else if (message.direction == EMMessageDirectionReceive) {
//        NSString *headImg = [NSString stringWithFormat:@"%@%@",FILE_PATH,_relatives.imagePath];
//        model.avatarURLPath = headImg;
//    }
//    return model;
//}


#pragma mark - EaseMessageViewControllerDelegate

- (UITableViewCell *)messageViewController:(UITableView *)tableView cellForMessageModel:(id<IMessageModel>)model
{
    if ([model.message.ext objectForKey:@"msgtype"]) {
        NSString *CellIdentifier = [EaseMessageCell cellIdentifierWithModel:model];
        EaseMessageCell *cell = (EaseMessageCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (cell == nil) {
            cell = [[EaseMessageCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier model:model];
            cell.selectionStyle = UITableViewCellSelectionStyleNone;
        }
        cell.model = model;
        cell.delegate = self;
    }
    return nil;
}


- (CGFloat)messageViewController:(EaseMessageViewController *)viewController
           heightForMessageModel:(id<IMessageModel>)messageModel
                   withCellWidth:(CGFloat)cellWidth
{
    if ([messageModel.message.ext objectForKey:@"msgtype"]) {
        return 110;
    }
    return 0.f;
}

-(void)messageCellSelected:(id<IMessageModel>)model{
    if ([model.message.ext objectForKey:@"msgtype"]) {
        NSLog(@"------你點(diǎn)了自定義cell------");
    }
}

//長按收拾回調(diào)樣例:
- (BOOL)messageViewController:(EaseMessageViewController *)viewController
   canLongPressRowAtIndexPath:(NSIndexPath *)indexPath
{
    //樣例給出的邏輯是所有cell都允許長按
    return YES;
}

- (void)messagesDidRead:(NSArray *)aMessages{
    NSLog(@"已讀回執(zhí)");
}

#pragma mark - Private

-(void)touchRightButton{
    NSDictionary *messageExt = @{
                                 @"msgtype":@"025",
                                 @"userId":@"chenchenchenchen",
                                 @"userHeadImg":@"sisisisi",
                                 @"userName":@"yanyanyanyanyan我是自定義的cell"
                                 };
    
    [self sendTextMessage:@"我可以永遠(yuǎn)笑著扮演你的配角 在你的背后自己煎熬 如果你不想要  想退出要趁早" withExt:messageExt];
}
@end

仿照環(huán)信的cell寫一個(gè)EaseBubbleView的分類

7059D1AB-3B8F-49FB-AE47-A1A7B587C7C4.png
import "EaseBubbleView.h"

@interface EaseBubbleView (TopicText)

/*!
 @method
 @brief 構(gòu)建文本類型消息氣泡視圖
 @discussion
 @result
 */
- (void)setupTextBubbleViewTopic;

/*!
 @method
 @brief 變更文本類型消息氣泡的邊距躏鱼,并更新改子視圖約束
 @discussion
 @param margin 氣泡邊距
 @result
 */
- (void)updateTextMarginTopic:(UIEdgeInsets)margin;

@end

#import "EaseBubbleView+Text.h"

@implementation EaseBubbleView (Text)

#pragma mark - private

- (void)_setupTextBubbleMarginConstraintsTopic
{
    NSLayoutConstraint *marginTopConstraint = [NSLayoutConstraint constraintWithItem:self.textLabel attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.backgroundImageView attribute:NSLayoutAttributeTop multiplier:1.0 constant:self.margin.top];
    NSLayoutConstraint *marginLeftConstraint = [NSLayoutConstraint constraintWithItem:self.textLabel attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.backgroundImageView attribute:NSLayoutAttributeRight multiplier:1.0 constant:-self.margin.right];
    NSLayoutConstraint *marginRightConstraint = [NSLayoutConstraint constraintWithItem:self.textLabel attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.backgroundImageView attribute:NSLayoutAttributeLeft multiplier:1.0 constant:self.margin.left];
    NSLayoutConstraint *marginRightConstraintHeight = [NSLayoutConstraint constraintWithItem:self.textLabel attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:self.backgroundImageView attribute:NSLayoutAttributeHeight multiplier:0.5 constant:0];

    [self.marginConstraints removeAllObjects];
    [self.marginConstraints addObject:marginTopConstraint];
    [self.marginConstraints addObject:marginLeftConstraint];
    [self.marginConstraints addObject:marginRightConstraint];
    [self.marginConstraints addObject:marginRightConstraintHeight];

    [self addConstraints:self.marginConstraints];
}

- (void)_setupTextBubbleConstraintsTopic
{
    [self _setupTextBubbleMarginConstraintsTopic];
    //增加新控件約束
    [self addConstraint:[NSLayoutConstraint constraintWithItem:self.myTextLabel attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.backgroundImageView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:-10]];
    [self addConstraint:[NSLayoutConstraint constraintWithItem:self.myTextLabel attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.textLabel attribute:NSLayoutAttributeRight multiplier:1.0 constant:-self.margin.right]];
    [self addConstraint:[NSLayoutConstraint constraintWithItem:self.myTextLabel attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.textLabel attribute:NSLayoutAttributeLeft multiplier:1.0 constant:self.margin.left]];
    [self addConstraint:[NSLayoutConstraint constraintWithItem:self.myTextLabel attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:self.backgroundImageView attribute:NSLayoutAttributeHeight multiplier:0.3 constant:0]];
}

#pragma mark - public

- (void)setupTextBubbleViewTopic
{
    self.textLabel = [[UILabel alloc] init];
    self.textLabel.translatesAutoresizingMaskIntoConstraints = NO;
    self.textLabel.backgroundColor = [UIColor clearColor];
    self.textLabel.numberOfLines = 2;
    [self.backgroundImageView addSubview:self.textLabel];
    
    // 新的UI控件
    self.myTextLabel = [[UILabel alloc]init];
    self.myTextLabel.font = [UIFont systemFontOfSize:12];
    self.myTextLabel.backgroundColor = [UIColor orangeColor];
    self.myTextLabel.translatesAutoresizingMaskIntoConstraints = NO;
    [self.backgroundImageView addSubview:self.myTextLabel];
    [self _setupTextBubbleConstraintsTopic];
}

- (void)updateTextMarginTopic:(UIEdgeInsets)margin
{
    if (_margin.top == margin.top && _margin.bottom == margin.bottom && _margin.left == margin.left && _margin.right == margin.right) {
        return;
    }
    _margin = margin;
    
    [self removeConstraints:self.marginConstraints];
    [self _setupTextBubbleMarginConstraintsTopic];
}

@end

然后在EaseMessageCell里仿寫環(huán)信的cell,判斷是不是擴(kuò)展消息殷绍,

//渲染
  case EMMessageBodyTypeText:
            {
                if ([model.message.ext objectForKey:@"msgtype"]) {
                    [_bubbleView setupTextBubbleViewTopic];
                    _bubbleView.textLabel.font = _messageTextFont;
                    _bubbleView.textLabel.textColor = _messageTextColor;
                }else{
                    [_bubbleView setupTextBubbleView];
                    _bubbleView.textLabel.font = _messageTextFont;
                    _bubbleView.textLabel.textColor = _messageTextColor;
                }
            }
                break;

//數(shù)據(jù)模型
 case EMMessageBodyTypeText:
            {
                if ([self.model.message.ext objectForKey:@"msgtype"]) {
                    _bubbleView.textLabel.attributedText = [[EaseEmotionEscape sharedInstance] attStringFromTextForChatting:model.text textFont:self.messageTextFont];
                    _bubbleView.myTextLabel.text = [self.model.message.ext objectForKey:@"userName"];
                }else{
                    _bubbleView.textLabel.attributedText = [[EaseEmotionEscape sharedInstance] attStringFromTextForChatting:model.text textFont:self.messageTextFont];
                }
            }
                break;

//跟新約束
case EMMessageBodyTypeText:
            {
                if ([self.model.message.ext objectForKey:@"msgtype"]) {
                    [_bubbleView updateTextMarginTopic:_bubbleMargin];
                }else{
                    [_bubbleView updateTextMargin:_bubbleMargin];
                }
            }
                break;

//cell的點(diǎn)擊事件
case EMMessageBodyTypeText:
            {
                if ([_delegate respondsToSelector:@selector(messageCellSelected:)]) {
                    [_delegate messageCellSelected:_model];
                }
            }
                break;

//獲取cell的重用標(biāo)識
case EMMessageBodyTypeText:
                if ([model.message.ext objectForKey:@"msgtype"]) {
                    cellIdentifier = EaseMessageCellIdentifierSendTextTTopic;
                }else{
                    cellIdentifier = EaseMessageCellIdentifierSendText;
                }
                break;
case EMMessageBodyTypeText:
                if ([model.message.ext objectForKey:@"msgtype"]) {
                    cellIdentifier = EaseMessageCellIdentifierRecvTextTTopic;
                }else{
                    cellIdentifier = EaseMessageCellIdentifierRecvText;
                }
                break;
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末染苛,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子主到,更是在濱河造成了極大的恐慌茶行,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,682評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件登钥,死亡現(xiàn)場離奇詭異畔师,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)牧牢,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評論 3 395
  • 文/潘曉璐 我一進(jìn)店門看锉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人塔鳍,你說我怎么就攤上這事伯铣。” “怎么了轮纫?”我有些...
    開封第一講書人閱讀 165,083評論 0 355
  • 文/不壞的土叔 我叫張陵腔寡,是天一觀的道長。 經(jīng)常有香客問我掌唾,道長放前,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,763評論 1 295
  • 正文 為了忘掉前任郑兴,我火速辦了婚禮犀斋,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘情连。我一直安慰自己叽粹,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,785評論 6 392
  • 文/花漫 我一把揭開白布却舀。 她就那樣靜靜地躺著虫几,像睡著了一般。 火紅的嫁衣襯著肌膚如雪挽拔。 梳的紋絲不亂的頭發(fā)上辆脸,一...
    開封第一講書人閱讀 51,624評論 1 305
  • 那天,我揣著相機(jī)與錄音螃诅,去河邊找鬼啡氢。 笑死状囱,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的倘是。 我是一名探鬼主播亭枷,決...
    沈念sama閱讀 40,358評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼搀崭!你這毒婦竟也來了叨粘?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,261評論 0 276
  • 序言:老撾萬榮一對情侶失蹤瘤睹,失蹤者是張志新(化名)和其女友劉穎升敲,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體轰传,經(jīng)...
    沈念sama閱讀 45,722評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡驴党,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了绸吸。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鼻弧。...
    茶點(diǎn)故事閱讀 40,030評論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖锦茁,靈堂內(nèi)的尸體忽然破棺而出攘轩,到底是詐尸還是另有隱情,我是刑警寧澤码俩,帶...
    沈念sama閱讀 35,737評論 5 346
  • 正文 年R本政府宣布度帮,位于F島的核電站,受9級特大地震影響稿存,放射性物質(zhì)發(fā)生泄漏笨篷。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,360評論 3 330
  • 文/蒙蒙 一瓣履、第九天 我趴在偏房一處隱蔽的房頂上張望率翅。 院中可真熱鬧,春花似錦袖迎、人聲如沸冕臭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽辜贵。三九已至,卻和暖如春归形,著一層夾襖步出監(jiān)牢的瞬間托慨,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評論 1 270
  • 我被黑心中介騙來泰國打工暇榴, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留厚棵,地道東北人蕉世。 一個(gè)月前我還...
    沈念sama閱讀 48,237評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像婆硬,于是被迫代替她去往敵國和親讨彼。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,976評論 2 355