好友推荐---环信发送名片(自定义视图)消息

在集成环信即时通讯的基础上,要做好友推荐的功能,查了下SDK发现里面提供了自定义消息的接口,接下来我们就可以根据自己的需要去自定义消息视图了

- (UITableViewCell *)messageViewController:(UITableView *)tableView cellForMessageModel:(id<IMessageModel>)messageModel{

环信的注释是: 获取消息自定义cell
用户根据messageModel判断是否显示自定义cell,返回nil显示默认cell,否则显示用户自定义cell

既然提供了方法,那么接下来我们就可以根据自己的需求去操作了(这里只做好友推荐的视图)

首先创建了继承EaseBaseMessageCell的自定义消息视图(有些博友问我后面不执行代理方法,在这里特此说明下,我是继承重写的,好多方法都是自己添加的,请留意你们的项目是直接修改还是继承)

.h

@interface IMChatBusinessCardCell : EaseBaseMessageCell

@end

.m

#import "IMChatBusinessCardCell.h"
#import "EaseBubbleView+IMChatBusinessCard.h"

static const CGFloat kCellHeight = 110.0f;

@implementation IMChatBusinessCardCell

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

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

- (void)setCustomModel:(id)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)model{
    [_bubbleView setupBusinessCardBubbleView];

    _bubbleView.imageView.image = [UIImage imageNamed:@"shouyeliaotiankuangbai"];
}

- (void)updateCustomBubbleViewMargin:(UIEdgeInsets)bubbleMargin model:(id)mode{
    [_bubbleView updateBusinessCardMargin:bubbleMargin];
    _bubbleView.translatesAutoresizingMaskIntoConstraints = YES;

    CGFloat bubbleViewHeight = 84;// 气泡背景图高度
    CGFloat nameLabelHeight = 15;// 昵称label的高度

    if (mode.isSender) {
        _bubbleView.frame =
        CGRectMake([UIScreen mainScreen].bounds.size.width - 273.5, nameLabelHeight, 213, bubbleViewHeight);
    }else{
        _bubbleView.frame = CGRectMake(55, nameLabelHeight, 213, bubbleViewHeight);

    }
    // 这里强制调用内部私有方法
    [_bubbleView _setupConstraintsXX];

}

- (NSString *)cellIdentifierWithModel:(id)model{
    return NSStringFromClass([self class]);
}

- (CGFloat)cellHeightWithModel:(id)model{
    return kCellHeight;
}

- (void)setModel:(id)model{
    [super setModel:model];
    NSDictionary *dict = model.message.ext;
    self.bubbleView.userNameLabel.text = dict[@"cardUserName"];
    self.bubbleView.userPhoneLabel.text = dict[@"cardUserPhone"];
    _hasRead.hidden = YES;//名片消息不显示已读
}

- (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;
}

在这里我们需要将控件的属性接口放出来,在这里有两种方式,一种是直接在EaseBubbleView里自行添加,还有一种是创建它的Category.这里采用第二种方式

.h

#import "EaseBubbleView.h"

@interface EaseBubbleView (IMChatBusinessCard)

// 用户头像
@property (strong, nonatomic) UIImageView *userHeaderImageView;

// 用户昵称
@property (strong, nonatomic) UILabel *userNameLabel;

// 用户手机号
@property (strong, nonatomic) UILabel *userPhoneLabel;

// 分割线
@property (strong, nonatomic) UIView *line;

// tip标签
@property (strong, nonatomic) UILabel *tipsLabel;

// 设置名片气泡
- (void)setupBusinessCardBubbleView;

// 更新名片间距
- (void)updateBusinessCardMargin:(UIEdgeInsets)margin;

// 设置约束
- (void)_setupConstraintsXX;

@end

.m

#import "EaseBubbleView+IMChatBusinessCard.h"
#import 

static char _userHeaderImageView_;
static char _userNameLabel_;
static char _userPhoneLabel_;
static char _line_;
static char _tipsLabel_;
@implementation EaseBubbleView (IMChatBusinessCard)

- (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];
}

#pragma mark - public
- (void)setupBusinessCardBubbleView{
    // 头像
    self.userHeaderImageView = [UIImageView new];
    [self.userHeaderImageView setImage:[UIImage imageNamed:STR_DEFAULT_APPIMAGE]];
    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

现在都定义好了,再回到自定义消息样式的方法中添加判断就好了

- (UITableViewCell *)messageViewController:(UITableView *)tableView cellForMessageModel:(id)messageModel{
    if (messageModel.bodyType == EMMessageBodyTypeText &&
        [[messageModel text] hasPrefix:@"[名片]"]) {
        NSString *CellIdentifier = [IMChatBusinessCardCell cellIdentifierWithModel:messageModel];
        IMChatBusinessCardCell *cell = (IMChatBusinessCardCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (cell == nil) {
            cell = [[IMChatBusinessCardCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier model:messageModel];
            cell.selectionStyle = UITableViewCellSelectionStyleNone;
        }
        cell.model = messageModel;
        return cell;
    }
    return nil;
}

说到这里,那么当我们推荐事件触发的时候要怎么做呢,这里我随便给了些假数据,仅供参考

- (void)sendRecommendFriend{
    RMLog(@"发送推荐好友");
    EMMessage *message = [EaseSDKHelper sendTextMessage:@"[名片]"
                                                     to:@"600018"
                                            messageType:EMChatTypeChat
                                             messageExt:@{@"cardUserName":@"Raymon",@"cardUserPhone":@"13843838438"}];
    [[EMClient sharedClient].chatManager sendMessage:message progress:^(int progress) {
        RMLog(@"%d",progress);
    } completion:^(EMMessage *message, EMError *error) {
        TXHChatViewController *chatController = [[TXHChatViewController alloc] initWithConversationChatter:@"600018" conversationType:EMConversationTypeChat];
        [self.navigationController pushViewController:chatController animated:YES];
    }];
}

到这里,我们发送名片的功能已经做完,但可能也会有人和我一样,如果要点击名片,要怎么去做呢,这里我问了下技术咨询,是让我在EaseMessageCell的bubbleViewTapAction方法中只保留

if ([_delegate respondsToSelector:@selector(messageCellSelected:)]) {
                [_delegate messageCellSelected:_model];
                return;
            }

这一句,开始我也感觉其余的判断是多余的,这样就完全可以了,但是后面发现如果这样修改后,到了后面自己要写的和判断的就要好多,所以变化了下思路,在EaseMessageViewController中添加了个点击自定义视图(名片)消息的协议,在- (void)messageCellSelected:(id)model
switch判断中协议

case EMMessageBodyTypeText:
        {
            if ([_delegate respondsToSelector:@selector(didSelectMessageModel:)]) {
                [_delegate didSelectMessageModel:model];
            }
        }

然后在回到自己的控制器中进行判断,个人感觉这样可能更方便些吧

- (void)didSelectMessageModel:(id<IMessageModel>)messageModel{
    if (messageModel.bodyType == EMMessageBodyTypeText &&
        [[messageModel text] hasPrefix:@"[名片]"]){
        // 点击名片
        RMLog(@"点击名片");
    }
}

好友推荐暂时就到这里,后续还有好多功能,这里只是积累下自己的开发心得和体会,也给自己留个记录备注.而这些主要是参考了环信Demo里的红包功能去仿写的,当然开始也在网上查询了好多,都没有发现完整的.希望在这里一起学习

前往下载: http://download.csdn.net/download/sinat_28585351/9801988

特此声明,有些博友下载链接后说没有Demo,我提供的只是逻辑,发送红包和其他自定义视图都可适用,而链接下载的只是自定义的名片类,本身就不是完整的Demo,自行选择下载,可以把下载后的类文件直接拷贝道项目中使用,不会用就乱喷的请绕行

你可能感兴趣的:(iOS开发)