您的位置:首页 > 移动开发 > 微信开发

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

2017-04-02 11:05 218 查看
在集成环信即时通讯的基础上,要做好友推荐的功能,查了下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<IMessageModel>)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<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)model{
[_bubbleView setupBusinessCardBubbleView];

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

- (void)updateCustomBubbleViewMargin:(UIEdgeInsets)bubbleMargin model:(id<IMessageModel>)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<IMessageModel>)model{
return NSStringFromClass([self class]);
}

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

- (void)setModel:(id<IMessageModel>)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 <objc/runtime.h>

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<IMessageModel>)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<IMessageModel>)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,自行选择下载,可以把下载后的类文件直接拷贝道项目中使用,不会用就乱喷的请绕行
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息