环信发送名片初试

实现思路,跟着官方的红包cell来写。这里写得有点简陋,只是跟有一样需求的人提供下思路,可能写得不对,还望指教。

一、新建一个cell,父类是EaseBaseMessageCell

#import "EaseBaseMessageCell.h"

/**
 *  名片cell
 */
@interface BSBusinessCardCell : EaseBaseMessageCell

@end

二、参照红包cell改成自己项目里需要的

#import "BSBusinessCardCell.h"
#import "UIImageView+EMWebCache.h"
#import "EaseBubbleView+BusinessCard.h"

static const CGFloat kCellHeight = 110.0f;

@implementation BSBusinessCardCell

#pragma mark - IModelCell

- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier model:(id<IMessageModel>)model
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier model:model];
    
    if (self) {
        self.hasRead.hidden = YES;
        self.selectionStyle = UITableViewCellSelectionStyleNone;
    }
    
    return self;
}

- (BOOL)isCustomBubbleView:(id<IMessageModel>)model
{
    return YES;
}

- (void)setCustomModel:(id<IMessageModel>)model
{
    UIImage *image = model.image;
    if (!image) {
        [self.bubbleView.imageView sd_setImageWithURL:[NSURL URLWithString:model.fileURLPath] placeholderImage:[UIImage imageNamed:model.failImageName]];
    } else {
        _bubbleView.imageView.image = image;
    }
    
    if (model.avatarURLPath) {
        [self.avatarView sd_setImageWithURL:[NSURL URLWithString:model.avatarURLPath] placeholderImage:model.avatarImage];
    } else {
        self.avatarView.image = model.avatarImage;
    }
}

- (void)setCustomBubbleView:(id<IMessageModel>)model
{
    [_bubbleView setupBusinessCardBubbleView];
    
    _bubbleView.imageView.image = [UIImage imageNamed:@"imageDownloadFail"];
}

- (void)updateCustomBubbleViewMargin:(UIEdgeInsets)bubbleMargin model:(id<IMessageModel>)model
{
    [_bubbleView updateBusinessCardMargin:bubbleMargin];
    _bubbleView.translatesAutoresizingMaskIntoConstraints = YES;
    
    CGFloat bubbleViewHeight = 84;// 气泡背景图高度
    CGFloat nameLabelHeight = 15;// 昵称label的高度
    
    if (model.isSender) {
        _bubbleView.frame =
        CGRectMake([UIScreen mainScreen].bounds.size.width - 273.5, nameLabelHeight, 213, bubbleViewHeight);
//        self.bubbleView.userHeaderImageView.frame = CGRectMake(13, 19, 26, 34);
//        self.bubbleView.userNameLabel.frame = CGRectMake(48, 19, 156, 15);
//        self.bubbleView.userPhoneLabel.frame = CGRectMake(48, 41, 49, 12);
//        self.bubbleView.line.frame = CGRectMake(13, 73, 200, 1);
//        self.bubbleView.tipsLabel.frame = CGRectMake(145, 73, 80, 20);
    }else{
        _bubbleView.frame = CGRectMake(55, nameLabelHeight, 213, bubbleViewHeight);
//        self.bubbleView.userHeaderImageView.frame = CGRectMake(20, 19, 26, 34);
//        self.bubbleView.userNameLabel.frame = CGRectMake(55, 19, 156, 15);
//        self.bubbleView.userPhoneLabel.frame = CGRectMake(55, 41, 49, 12);
//        self.bubbleView.line.frame = CGRectMake(20, 73, 200, 1);
//        self.bubbleView.tipsLabel.frame = CGRectMake(152, 73, 80, 20);
        
    }
    // 这里强制调用内部私有方法
    [_bubbleView _setupConstraintsXX];

}

+ (NSString *)cellIdentifierWithModel:(id<IMessageModel>)model
{
    return NSStringFromClass([self class]);
//    return model.isSender ? @"__redPacketCellSendIdentifier__" : @"__redPacketCellReceiveIdentifier__";
}

+ (CGFloat)cellHeightWithModel:(id<IMessageModel>)model
{
    return kCellHeight;
}

- (void)setModel:(id<IMessageModel>)model
{
    [super setModel:model];
    
    NSDictionary *dict = model.message.ext;
//    [model nickname]; // 谁发送的这个名片,谁向你推荐一张名片
    /*
     {
         cardUserAvatarURLString = xs;
         cardUserName = xs;
         cardUserPhone = xs;
     }
     
     */
    self.bubbleView.userNameLabel.text = dict[@"cardUserName"];
    self.bubbleView.userPhoneLabel.text = dict[@"cardUserPhone"];
//    NSString *str = [NSString stringWithFormat:@"%@",[dict valueForKey:RedpacketKeyRedpacketGreeting]];
//    if (str.length > 10) {
//        str = [str substringToIndex:8];
//        str = [str stringByAppendingString:@"..."];
//        self.bubbleView.redpacketTitleLabel.text = str;
//    }else
//    {
//        self.bubbleView.redpacketTitleLabel.text = [dict valueForKey:RedpacketKeyRedpacketGreeting];
//    }
//    
//    self.bubbleView.redpacketSubLabel.text = @"查看红包";
//    self.bubbleView.redpacketNameLabel.text = [dict valueForKey:RedpacketKeyRedpacketOrgName];
//    if ([[dict valueForKey:RedpacketKeyRedapcketToAnyone] isEqualToString:@"member"]) {
//        self.bubbleView.redpacketMemberLable.text = @"专属红包";
//    }else
//    {
//        self.bubbleView.redpacketMemberLable.text = @"";
//    }
    _hasRead.hidden = YES;//名片消息不显示已读
//    _nameLabel = nil;// 不显示姓名
    
}

- (void)layoutSubviews
{
    [super layoutSubviews];
    
    NSString *imageName = self.model.isSender ? @"RedpacketCellResource.bundle/redpacket_sender_bg" : @"RedpacketCellResource.bundle/redpacket_receiver_bg";
    UIImage *image = self.model.isSender ? [[UIImage imageNamed:imageName] stretchableImageWithLeftCapWidth:30 topCapHeight:35] :
    [[UIImage imageNamed:imageName] stretchableImageWithLeftCapWidth:20 topCapHeight:35];
    // 等待接入名片的背景图片
//    self.bubbleView.backgroundImageView.image = image;
}


@end

三、再针对EaseBubbleView写个分类,关联一些名片所需要的控件,当然也可以像环信默认支持的那几种

cell上直接把属性写在EaseBubbleView类里。

四,头文件里写上自己需要的属性,以及需要外界访问的方法

#import "EaseBubbleView.h"

@interface EaseBubbleView (BusinessCard)

/**
 *  用户的头像
 */
@property (strong, nonatomic) UIImageView *userHeaderImageView;
/**
 *  用户的昵称
 */
@property (strong, nonatomic) UILabel *userNameLabel;
/**
 *  用户的手机号
 */
@property (strong, nonatomic) UILabel *userPhoneLabel;
/**
 *  分隔线
 */
@property (strong, nonatomic) UIView  *line;
/**
 *  提示字 “个人名片”
 */
@property (strong, nonatomic) UILabel *tipsLabel;

- (void)setupBusinessCardBubbleView;

- (void)updateBusinessCardMargin:(UIEdgeInsets)margin;

- (void)_setupConstraintsXX;
@end

五、.m文件示例写法

#import "EaseBubbleView+BusinessCard.h"
#import <objc/runtime.h>

static char _userHeaderImageView_;
static char _userNameLabel_;
static char _userPhoneLabel_;
static char _line_;
static char _tipsLabel_;
@implementation EaseBubbleView (BusinessCard)
#pragma mark - private
- (void)_setupConstraintsXX
{
    [self.marginConstraints removeAllObjects];

    //userHeaderImageView
    NSLayoutConstraint *userHeaderImageViewTopConstraint =
    [NSLayoutConstraint constraintWithItem:self.userHeaderImageView
                                 attribute:NSLayoutAttributeTop
                                 relatedBy:NSLayoutRelationEqual
                                    toItem:self.backgroundImageView
                                 attribute:NSLayoutAttributeTop
                                multiplier:1.0
                                  constant:10];
    
    NSLayoutConstraint *userHeaderImageViewLeadingConstraint =
    [NSLayoutConstraint constraintWithItem:self.userHeaderImageView
                                 attribute:NSLayoutAttributeLeading
                                 relatedBy:NSLayoutRelationEqual
                                    toItem:self.backgroundImageView
                                 attribute:NSLayoutAttributeLeading
                                multiplier:1.0
                                  constant:10];
    
    [self.marginConstraints addObject:userHeaderImageViewTopConstraint];
    [self.marginConstraints addObject:userHeaderImageViewLeadingConstraint];
    
    NSLayoutConstraint *userHeaderImageViewHeightConstraint =
    [NSLayoutConstraint constraintWithItem:self.userHeaderImageView
                                 attribute:NSLayoutAttributeHeight
                                 relatedBy:NSLayoutRelationEqual
                                    toItem:nil
                                 attribute:NSLayoutAttributeNotAnAttribute
                                multiplier:0.0
                                  constant:36];
    
    NSLayoutConstraint *userHeaderImageViewWidthConstraint =
    [NSLayoutConstraint constraintWithItem:self.userHeaderImageView
                                 attribute:NSLayoutAttributeWidth
                                 relatedBy:NSLayoutRelationEqual
                                    toItem:nil
                                 attribute:NSLayoutAttributeNotAnAttribute
                                multiplier:0.0
                                  constant:36];
    
    [self.userHeaderImageView addConstraint:userHeaderImageViewHeightConstraint];
    [self.userHeaderImageView addConstraint:userHeaderImageViewWidthConstraint];
    
    // userNameLabel
    NSLayoutConstraint *userNameLabelWithMarginTopConstraint =
    [NSLayoutConstraint constraintWithItem:self.userNameLabel
                                 attribute:NSLayoutAttributeTop
                                 relatedBy:NSLayoutRelationEqual
                                    toItem:self.userHeaderImageView
                                 attribute:NSLayoutAttributeTop
                                multiplier:1.0
                                  constant:2];
    
    NSLayoutConstraint *userNameLabelWithMarginRightConstraint =
    [NSLayoutConstraint constraintWithItem:self.userNameLabel
                                 attribute:NSLayoutAttributeTrailing
                                 relatedBy:NSLayoutRelationEqual
                                    toItem:self.backgroundImageView
                                 attribute:NSLayoutAttributeTrailing
                                multiplier:1.0
                                  constant:-self.margin.right];
    
    NSLayoutConstraint *userNameLabelWithMarginLeftConstraint =
    [NSLayoutConstraint constraintWithItem:self.userNameLabel
                                 attribute:NSLayoutAttributeLeading
                                 relatedBy:NSLayoutRelationEqual
                                    toItem:self.userHeaderImageView
                                 attribute:NSLayoutAttributeTrailing
                                multiplier:1.0
                                  constant:10];
    
    [self.marginConstraints addObject:userNameLabelWithMarginRightConstraint];
    [self.marginConstraints addObject:userNameLabelWithMarginTopConstraint];
    [self.marginConstraints addObject:userNameLabelWithMarginLeftConstraint];
    
    // userPhoneLabel
    NSLayoutConstraint *userPhoneLabelTopConstraint =
    [NSLayoutConstraint constraintWithItem:self.userPhoneLabel
                                 attribute:NSLayoutAttributeBottom
                                 relatedBy:NSLayoutRelationEqual
                                    toItem:self.userHeaderImageView
                                 attribute:NSLayoutAttributeBottom
                                multiplier:1.0
                                  constant:1];
  
    NSLayoutConstraint *userPhoneLabelLeftConstraint =
    [NSLayoutConstraint constraintWithItem:self.userPhoneLabel
                                 attribute:NSLayoutAttributeLeading
                                 relatedBy:NSLayoutRelationEqual
                                    toItem:self.userNameLabel
                                 attribute:NSLayoutAttributeLeading
                                multiplier:1.0
                                  constant:0];
    NSLayoutConstraint *userPhoneLabelRightConstraint =
    [NSLayoutConstraint constraintWithItem:self.userPhoneLabel
                                 attribute:NSLayoutAttributeTrailing
                                 relatedBy:NSLayoutRelationEqual
                                    toItem:self.backgroundImageView
                                 attribute:NSLayoutAttributeTrailing
                                multiplier:1.0
                                  constant:-self.margin.right];
    
    [self.marginConstraints addObject:userPhoneLabelTopConstraint];
    [self.marginConstraints addObject:userPhoneLabelLeftConstraint];
    [self.marginConstraints addObject:userPhoneLabelRightConstraint];


    //  line
    NSLayoutConstraint *lineTopConstraint =
    [NSLayoutConstraint constraintWithItem:self.line
                                 attribute:NSLayoutAttributeTop
                                 relatedBy:NSLayoutRelationEqual
                                    toItem:self.userHeaderImageView
                                 attribute:NSLayoutAttributeBottom
                                multiplier:1.0
                                  constant:10];
    
    NSLayoutConstraint *lineLeftConstraint =
    [NSLayoutConstraint constraintWithItem:self.line
                                 attribute:NSLayoutAttributeLeading
                                 relatedBy:NSLayoutRelationEqual
                                    toItem:self.userHeaderImageView
                                 attribute:NSLayoutAttributeLeading
                                multiplier:1.0
                                  constant:0];
    
    NSLayoutConstraint *lineRightConstraint =
    [NSLayoutConstraint constraintWithItem:self.line
                                 attribute:NSLayoutAttributeTrailing
                                 relatedBy:NSLayoutRelationEqual
                                    toItem:self.backgroundImageView
                                 attribute:NSLayoutAttributeTrailing
                                multiplier:1.0
                                  constant:-self.margin.right];
    
    NSLayoutConstraint *lineHeightConstraint =
    [NSLayoutConstraint constraintWithItem:self.line
                                 attribute:NSLayoutAttributeHeight
                                 relatedBy:NSLayoutRelationEqual
                                    toItem:nil
                                 attribute:NSLayoutAttributeNotAnAttribute
                                multiplier:0.0
                                  constant:1];
    
    [self.marginConstraints addObject:lineTopConstraint];
    [self.marginConstraints addObject:lineLeftConstraint];
    [self.marginConstraints addObject:lineRightConstraint];
    [self.marginConstraints addObject:lineHeightConstraint];

    // tipsLabel
    NSLayoutConstraint *tipsLabelTopConstraint =
    [NSLayoutConstraint constraintWithItem:self.tipsLabel
                                 attribute:NSLayoutAttributeTop
                                 relatedBy:NSLayoutRelationEqual
                                    toItem:self.line
                                 attribute:NSLayoutAttributeBottom
                                multiplier:1.0
                                  constant:4];
    
    NSLayoutConstraint *tipsLabelLeftConstraint =
    [NSLayoutConstraint constraintWithItem:self.tipsLabel
                                 attribute:NSLayoutAttributeLeading
                                 relatedBy:NSLayoutRelationEqual
                                    toItem:self.line
                                 attribute:NSLayoutAttributeLeading
                                multiplier:1.0
                                  constant:0];
    NSLayoutConstraint *tipsLabelRightConstraint =
    [NSLayoutConstraint constraintWithItem:self.tipsLabel
                                 attribute:NSLayoutAttributeTrailing
                                 relatedBy:NSLayoutRelationEqual
                                    toItem:self.line
                                 attribute:NSLayoutAttributeTrailing
                                multiplier:1.0
                                  constant:0];
    [self.marginConstraints addObject:tipsLabelTopConstraint];
    [self.marginConstraints addObject:tipsLabelLeftConstraint];
    [self.marginConstraints addObject:tipsLabelRightConstraint];
    

    [self addConstraints:self.marginConstraints];
    
    NSLayoutConstraint *backImageConstraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:0.0f constant:260];
    
    [self.superview addConstraint:backImageConstraint];
    
    /*
     UIView *backImageView = self.backgroundImageView;
     NSArray *backgroundConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[backImageView]-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(backImageView)];
     NSArray *backgroundConstraints2 = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[backImageView(==200)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(backImageView)];
     
     [self addConstraints:backgroundConstraints];
     [self addConstraints:backgroundConstraints2];
     */
}


#pragma mark - public
- (void)setupBusinessCardBubbleView {
    // 头像
    self.userHeaderImageView = [UIImageView new];
    [self.userHeaderImageView setImage:[UIImage imageNamed:@"聊天输入框名片按钮"]];
    self.userHeaderImageView.translatesAutoresizingMaskIntoConstraints = NO;

    [self.backgroundImageView addSubview:self.userHeaderImageView];
    // 昵称
    self.userNameLabel = [UILabel new];
    self.userNameLabel.font = [UIFont systemFontOfSize:15.0f];
    self.userNameLabel.textColor = [UIColor lightGrayColor];
    self.userNameLabel.translatesAutoresizingMaskIntoConstraints = NO;

    [self.backgroundImageView addSubview:self.userNameLabel];
    // 手机号
    self.userPhoneLabel = [UILabel new];
    self.userPhoneLabel.font = [UIFont systemFontOfSize:13.0f];
    self.userPhoneLabel.textColor = [UIColor lightGrayColor];
    self.userPhoneLabel.translatesAutoresizingMaskIntoConstraints = NO;

    [self.backgroundImageView addSubview:self.userPhoneLabel];
    // 分隔线
    self.line = [UIView new];
    self.line.backgroundColor = [UIColor blackColor];
    self.line.translatesAutoresizingMaskIntoConstraints = NO;

    [self.backgroundImageView addSubview:self.line];
    // 提示字 个人名片
    self.tipsLabel = [UILabel new];
    self.tipsLabel.text = @"个人名片";
    self.tipsLabel.font = [UIFont systemFontOfSize:12.0f];
    self.tipsLabel.textColor = [UIColor lightGrayColor];
    self.tipsLabel.translatesAutoresizingMaskIntoConstraints = NO;

    [self.backgroundImageView addSubview:self.tipsLabel];
    
    [self _setupConstraintsXX];
}
- (void)updateBusinessCardMargin:(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 _setupConstraintsXX];
}

#pragma mark - getter and setter

- (void)setUserHeaderImageView:(UIImageView *)userHeaderImageView
{
    objc_setAssociatedObject(self, &_userHeaderImageView_, userHeaderImageView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (UIImageView *)userHeaderImageView
{
    return objc_getAssociatedObject(self, &_userHeaderImageView_);
}

- (void)setUserNameLabel:(UILabel *)userNameLabel
{
    objc_setAssociatedObject(self, &_userNameLabel_, userNameLabel, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (UILabel *)userNameLabel
{
    return objc_getAssociatedObject(self, &_userNameLabel_);
}

- (void)setUserPhoneLabel:(UILabel *)userPhoneLabel
{
    objc_setAssociatedObject(self, &_userPhoneLabel_, userPhoneLabel, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (UILabel *)userPhoneLabel
{
    return objc_getAssociatedObject(self, &_userPhoneLabel_);
}

- (void)setLine:(UIView *)line
{
    objc_setAssociatedObject(self, &_line_, line, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (UIView *)line
{
    return objc_getAssociatedObject(self, &_line_);
}

- (void)setTipsLabel:(UILabel *)tipsLabel
{
    objc_setAssociatedObject(self, &_tipsLabel_, tipsLabel, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (UILabel *)tipsLabel
{
    return objc_getAssociatedObject(self, &_tipsLabel_);
}

@end

六、写一个控制器,父类是ChatViewController,然后在这个类里实现代理方法,特定cell显示,特定cell行高,或者你也可以像我一样直接在ChatViewController里实现代理方法,官网的红包里是参过继承方式实现的,还有注释,这是一个带有红包功能的聊天控制器。

看了环信的源码,感觉写红包SDK的人明显技术比之前写那些SDK的人技术好,当然如果你懂,你也在里面看到itcast。

#pragma mark - EaseMessageViewControllerDelegate
/// 遵守协议,为红包,名片提供自定义cell
- (UITableViewCell *)messageViewController:(UITableView *)tableView
                       cellForMessageModel:(id<IMessageModel>)messageModel {
    //样例为如果消息是文本消息显示用户自定义cell
    if (messageModel.bodyType == EMMessageBodyTypeText &&
        [[messageModel text] hasPrefix:@"[名片]"]) {
        NSString *CellIdentifier = [BSBusinessCardCell cellIdentifierWithModel:messageModel];
        //CustomMessageCell为用户自定义cell,继承了EaseBaseMessageCell
        BSBusinessCardCell *cell = (BSBusinessCardCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (cell == nil) {
            cell = [[BSBusinessCardCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier model:messageModel];
            cell.selectionStyle = UITableViewCellSelectionStyleNone;
        }
        cell.model = messageModel;
        return cell;
    }
    return nil;
}
/// 遵守协议,为红包,名片提供自定义高度
- (CGFloat)messageViewController:(EaseMessageViewController *)viewController
           heightForMessageModel:(id<IMessageModel>)messageModel
                   withCellWidth:(CGFloat)cellWidth
{
    //样例为如果消息是文本消息使用用户自定义cell的高度
    if (messageModel.bodyType == EMMessageBodyTypeText &&
        [[messageModel text] hasPrefix:@"[名片]"]) {
        //CustomMessageCell为用户自定义cell,继承了EaseBaseMessageCell
        return [BSBusinessCardCell cellHeightWithModel:messageModel];
    }
    return 0.f;
}

 后续还有很多事要做,点击这个名片,跳转到详细信息,如果是好友,则显示发消息,修改标签

如果不是好友则显示添加到通讯录,貌似微信做的是也可以修改标签,任重而道远,后面还有红包,

我想记录下此刻的状态,毕竟之前也没有搞过环信,这次是直接把环信官网的demo托到项目里来的

时间紧迫,没有办法

原文地址:https://www.cnblogs.com/songxing10000/p/5948069.html