iOS 环信 利用自定义消息(消息扩展ext)实现发红包功能

利用环信扩展消息实现发红包页面 效果如下:

iOS 环信 利用自定义消息(消息扩展ext)实现发红包功能_第1张图片
环信自定义发红包界面

iOS 环信 利用自定义消息(消息扩展ext)实现发红包功能_第2张图片
自定义消息版面

代码如下:

1、添加发红包入口:

环信自带的有五个栏目 根据需要 删除最后两个 再添加一个红包选项
MSChatViewController.m类中添加红包选项(也就是环信EaseUI中的EaseMessageViewController.m类 我只是把这个类拉出来改个名字)

//更新更多视图项目 删除最后两个默认选项
    [self.chatBarMoreView removeItematIndex:3];
    [self.chatBarMoreView removeItematIndex:3];
//添加红包选项
    [self.chatBarMoreView insertItemWithImage:[UIImage imageNamed:@"chat_redPacket_big"] highlightedImage:[UIImage imageNamed:@"chat_redPacket_big"] title:@"红包"];

2、处理红包点击事件

MSChatChildrenViewController.m类中(继承的MSChatViewController.m 也可以直接在MSChatViewController.m类中对应方法写)

#pragma mark - 更多版面的点击事件
//点击更多按钮对应的事件
-(void)messageViewController:(MSChatViewController *)viewController didSelectMoreView:(MSEaseChatBarMoreView *)moreView AtIndex:(NSInteger)index{
    //相册 视频 定位 自带
    //红包 自定义
    if (index == 3) {
        MSSendRedPacketViewController *vc =  (MSSendRedPacketViewController *)[MSChatViewController ms_showSBController:kSBMessageName withID:[MSSendRedPacketViewController className]];
//发红包页面 处理完红包消息后回调
        vc.callBack = ^(NSString * _Nonnull is_finish, NSString * _Nonnull money, NSString * _Nonnull redpacket_id, NSString * _Nonnull nick_name, NSString * _Nonnull u_pic, NSString * _Nonnull blessing_words, NSString * _Nonnull user_id, NSArray * _Nonnull sub_redpacket) {
            NSDictionary *dic = @{@"is_finish":is_finish,
                                  @"money":money,
                                  @"redpacket_id":redpacket_id,
                                  @"nick_name":nick_name,
                                  @"u_pic":u_pic,
                                  @"blessing_words":blessing_words,
                                  @"user_id":user_id,
                                  @"sub_redpacket":sub_redpacket,
                                  };
//发送对应的红包消息
            [self sendRedPacketWithInfo:dic];
        };
        [self.navigationController pushViewController:vc animated:YES];
    }
}

3、发红包执行事件

#pragma mark - 发红包==============================发红包==============发红包==============================发红包
/**
 * 发送红包 info红包详情字段
 * is_finish 是否被领取
 * nick_name 发红包用户昵称
 * u_pic 发红包用户头像
 * blessing_words 祝福语
 * user_id 发红包用户id
 * money 红包金额
 * sub_redpacket 子红包列表
 */
-(void)sendRedPacketWithInfo:(NSDictionary *)info{
    NSString *is_finish = [info objectForKey:@"is_finish"];
    NSString *redpacket_id = [info objectForKey:@"redpacket_id"];
    NSString *nick_name = [info objectForKey:@"nick_name"];
    NSString *u_pic = [info objectForKey:@"u_pic"];
    NSString *blessing_words = [info objectForKey:@"blessing_words"];
//    NSString *utf8Str = [NSString stringWithUTF8String:[blessing_words UTF8String]];
//    NSData *uniData = [utf8Str dataUsingEncoding:NSNonLossyASCIIStringEncoding];
//    NSString *goodStr = [[NSString alloc] initWithData:uniData encoding:NSUTF8StringEncoding];
//    NSString *goodStr = [blessing_words stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
    NSString *user_id = [info objectForKey:@"user_id"];
    NSString *money = [info objectForKey:@"money"];
    NSArray *sub_redpacket = [info objectForKey:@"sub_redpacket"];
    NSMutableDictionary *itemDic = [[NSMutableDictionary alloc]init];
    if (is_finish) {
        [itemDic setObject:is_finish forKey:@"is_finish"];
    }
    if (redpacket_id) {
        [itemDic setObject:redpacket_id forKey:@"redpacket_id"];
    }
    if (nick_name) {
        [itemDic setObject:nick_name forKey:@"nick_name"];
    }
    if (u_pic) {
        [itemDic setObject:u_pic forKey:@"u_pic"];
    }
    if (blessing_words) {
        [itemDic setObject:blessing_words forKey:@"blessing_words"];
    }
    if (user_id) {
        [itemDic setObject:user_id forKey:@"user_id"];
    }
    if (money) {
        [itemDic setObject:money forKey:@"money"];
    }
    if (sub_redpacket) {
        [itemDic setObject:sub_redpacket forKey:@"sub_redpacket"];
    }
    NSMutableDictionary *dicExt = [[NSMutableDictionary alloc]init];
    //is_finish redpacket_id blessing_words移到外层
    [dicExt setObject:is_finish forKey:@"is_finish"];
    [dicExt setObject:redpacket_id forKey:@"redpacket_id"];
    [dicExt setObject:blessing_words forKey:@"blessing_words"];
    [dicExt setObject:@"msg_red_packet" forKey:@"msg_type"];

    [dicExt setObject:itemDic forKey:@"msg_info"];
//红包相关所有的字段放在消息扩展里发送
    [self sendTextMessage:@"" withExt:dicExt];

以上红包消息已经发送成功

以下处理红包消息

4、设置用户昵称、用户头像、用户id扩展消息的新增字段

MSChatChildrenViewController.m类中(继承的MSChatViewController.m 也可以直接在MSChatViewController.m类中对应方法写)

#pragma mark - 聊天页面 设置用户信息=============================设置用户model 扩展消息ext
//在扩展消息中加上添加 用户昵称 用户头像 和 用户id 字段
-(id)messageViewController:(MSChatViewController *)viewController modelForMessage:(EMMessage *)message{
    id model = nil;
    model = [[EaseMessageModel alloc] initWithMessage:message];
//加载失败图片
    model.failImageName = @"imageDownloadFail";
//头像默认图片
    model.avatarImage = [UIImage imageNamed:@"default"];
//发送方扩展字段保存
    if (message.direction==EMMessageDirectionSend) {
        //发送的信息,显示自己昵称与头像 昵称不存在的话 用用户id代替
        model.avatarURLPath = [MSUserManager sharedInstance].loginModel.u_pic;
        if (![MSFactory isBlankString:[MSUserManager sharedInstance].loginModel.nick_name]) {
            model.nickname = [MSUserManager sharedInstance].loginModel.nick_name;
        }else{
            model.nickname = [MSUserManager sharedInstance].loginModel.user_id;
        }
        NSDictionary *extDic = @{@"IMname" : ([MSUserManager sharedInstance].loginModel.nick_name) ? ([MSUserManager sharedInstance].loginModel.nick_name) : ([MSUserManager sharedInstance].loginModel.user_id),
                                 @"IMicon" : [MSUserManager sharedInstance].loginModel.u_pic,
                                 @"IMuser_id" : [MSUserManager sharedInstance].loginModel.user_id      };
        NSMutableDictionary *mutableDic = [NSMutableDictionary dictionaryWithDictionary:model.message.ext];
//扩展消息新增字段
        [mutableDic addEntriesFromDictionary:extDic];
        model.message.ext = mutableDic;
        
}else{
        //对方环信帐号信息获取
    model.nickname = _nick_name ? _nick_name : @"";
    model.avatarURLPath = _headerStr ? _headerStr : @"";
        
    NSDictionary *extDic = @{@"IMname" : _nick_name ? _nick_name : @"",
                             @"IMicon" : _headerStr ? _headerStr : @"",
                             @"IMuser_id" : _user_id ? _user_id : @""                             };
    NSMutableDictionary *mutableDic = [NSMutableDictionary dictionaryWithDictionary:model.message.ext];
    [mutableDic addEntriesFromDictionary:extDic];
    model.message.ext = mutableDic;
    }
    return model;
}

5、注册并初始化红包cell

MSChatChildrenViewController.m类中(继承的MSChatViewController.m 也可以直接在MSChatViewController.m类中对应方法写)

#pragma mark - cell for row===============================cell for row代理方法 相当于父类的cell for row
-(UITableViewCell *)messageViewController:(UITableView *)tableView cellForMessageModel:(id)messageModel{
    if (messageModel.bodyType == EMMessageBodyTypeText) {
        NSDictionary *ext = [[NSDictionary alloc]initWithDictionary:messageModel.message.ext];
        NSLog(@"===%@===",ext);
        //红包类型
        if ([ext[@"msg_type"] isEqualToString:@"msg_red_packet"]) {
            NSString *CellIdentifier = [MSEaseMessageCell cellIdentifierWithModel:messageModel];
//自定义的红包cell
            MSCustomRedPacketCell *cell = (MSCustomRedPacketCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
            if (cell == nil) {
                
                cell = [[MSCustomRedPacketCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier model:messageModel];
                cell.selectionStyle = UITableViewCellSelectionStyleNone;
            }
            cell.model = messageModel;
            return cell;
        }
    }
//返回nil表示使用父类的cell样式
    return nil;
}

6、设置红包cell的高度

MSChatChildrenViewController.m类中(继承的MSChatViewController.m 也可以直接在MSChatViewController.m类中对应方法写)
红包消息的高度

#pragma mark - heightForMessageModel===============================heightForMessageModel
-(CGFloat)messageViewController:(MSChatViewController *)viewController heightForMessageModel:(id)messageModel withCellWidth:(CGFloat)cellWidth{
    if (messageModel.bodyType == EMMessageBodyTypeText ) {
        NSDictionary *ext = [[NSDictionary alloc]initWithDictionary:messageModel.message.ext];
        //红包类型
        if ([ext[@"msg_type"] isEqualToString:@"msg_red_packet"]) {
            CGFloat height = [MSCustomRedPacketCell cellHeightWithModel:messageModel];
            return height;
        }
        return 0.f;
    }
    return 0.f;
}

7、点击cell的执行事件

点击消息时对应的回调
MSChatViewController.m类中添加红包选项(也就是环信EaseUI中的EaseMessageViewController.m类 我只是把这个类拉出来改个名字)

#pragma mark - MSEaseMessageCellDelegate=====MSEaseMessageCellDelegate========================点击消息回调
//点击消息回调
- (void)messageCellSelected:(id)model
{
    if (_delegate && [_delegate respondsToSelector:@selector(messageViewController:didSelectMessageModel:)]) {
        BOOL flag = [_delegate messageViewController:self didSelectMessageModel:model];
        if (flag) {
            [self _sendHasReadResponseForMessages:@[model.message] isRead:YES];
            return;
        }
    }
    
    switch (model.bodyType) {
        case EMMessageBodyTypeText:
        {
            if (model.message.direction == EMMessageDirectionReceive && [model.message.ext count] > 0) {
                NSString *conferenceId = [model.message.ext objectForKey:@"conferenceId"];
                if ([conferenceId length] == 0) {
                    conferenceId = [model.message.ext objectForKey:@"em_conference_id"];
                }
                //时时音视频消息 使用的text类型的扩展
                if ([conferenceId length] > 0) {
                    [self _callMessageCellSelected:model];
                }
            }
            NSDictionary *ext = [[NSDictionary alloc]initWithDictionary:model.message.ext];
            //点击了红包类型
            if ([ext[@"msg_type"] isEqualToString:@"msg_red_packet"]) {
                NSDictionary *msgtypeDic = [[NSDictionary alloc]initWithDictionary:ext];
                NSLog(@"===%@===",msgtypeDic);
                MSRedPacketDetailModel *redPacketDetailModel = [MSRedPacketDetailModel modelWithJSON:msgtypeDic];
                //每次点击红包 先查询红包状态
                [self lookRedpacketDetailWithRedpacket_id:redPacketDetailModel.redpacket_id withModel:model withIsOpeningRedPacket:NO];
            }
        }
            break;
        case EMMessageBodyTypeImage:
        {
            _scrollToBottomWhenAppear = NO;
            [self _imageMessageCellSelected:model];
        }
            break;
        case EMMessageBodyTypeLocation:
        {
            [self _locationMessageCellSelected:model];
        }
            break;
        case EMMessageBodyTypeVoice:
        {
            [self _audioMessageCellSelected:model];
        }
            break;
        case EMMessageBodyTypeVideo:
        {
            [self _videoMessageCellSelected:model];
            
        }
            break;
        case EMMessageBodyTypeFile:
        {
            //自定义实现
            _scrollToBottomWhenAppear = NO;
            [self showHint:@"Custom implementation!"];
        }
            break;
        default:
            break;
    }
}

查询红包状态后 执行对应的操作

#pragma mark - 查询红包状态================================查询红包状态================================查询红包状态
/**
 * redpacket_id 当前点击的红包id
 * model 当前红包所在消息
 * isOpeningRedPacket 是否正在执行拆红包操作
 */
- (void)lookRedpacketDetailWithRedpacket_id:(NSString *)redpacket_id withModel:(id)IMModel withIsOpeningRedPacket:(BOOL)isOpeningRedPacket{
    NSDictionary *dic = @{
                          @"redpacket_id":redpacket_id,
                          };
    WEAK
    [[MacoNetworkManager Maco_networkGet_test:@"/appjson/redpacketDetail" parameters:dic] subscribeNext:^(id  _Nullable x) {
        NSLog(@"===%@===",x);
        STRONG
        MSBaseModel *model = [MSBaseModel modelWithJSON:x];
        if (model.code == 1) {
            NSLog(@"===%@===",model.data);
//保存当前红包状态model
            self.currentRedPacketDetailModel = [MSRedPacketDetailModel modelWithJSON:model.data];
            NSLog(@"my_user_id===%@===",[MSUserManager sharedInstance].loginModel.user_id);
            //判断红包是否是自己发送
            if (IMModel.isSender) {
               //根据当前查询到的红包领取状态 更新扩展消息
                    NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithDictionary:IMModel.message.ext];
                    [dic setObject:self.currentRedPacketDetailModel.is_finish forKey:@"is_finish"];
                    EMMessage *message = IMModel.message;
                    message.ext = dic;
//更新消息并保存到会话
                      [[EMClient sharedClient].chatManager updateMessage:message completion:^(EMMessage *aMessage, EMError *aError) {
//更新当前聊天列表
                          [self _updateMessageStatus:message];
                      }];
//红包过期
            if ([self.currentRedPacketDetailModel.is_finish intValue] == 2) {
                //进入红包过期提醒页面
                MSRedPacketOverdueViewController *vc =  (MSRedPacketOverdueViewController *)[[self class] ms_showSBController:kSBMessageName withID:[MSRedPacketOverdueViewController className]];
                vc.model = self.currentRedPacketDetailModel;
                vc.sub_redpacket = self.currentRedPacketDetailModel.sub_redpacket;
                [self.navigationController pushViewController:vc animated:YES];
//红包未过期 is_finish == 1 || is_finish == 0
            }else{
          //进入发送方红包详情页面
                MSRedPacketDetailViewController *vc =  (MSRedPacketDetailViewController *)[[self class] ms_showSBController:kSBMessageName withID:[MSRedPacketDetailViewController className]];
                vc.model = self.currentRedPacketDetailModel;
                vc.sub_redpacket = self.currentRedPacketDetailModel.sub_redpacket;
                [self.navigationController pushViewController:vc animated:YES];
            }
            }else{
                //不是自己发送的红包
                //还未领取 去领红包
                if ([self.currentRedPacketDetailModel.is_finish intValue] == 0) {
                    //领红包弹框
                    [self openRedPacketWithRedPacketDetailModel:self.currentRedPacketDetailModel withIMModel:IMModel];
                }else{
                   //红包已经领取或者红包过期 更新消息列表 并保存到会话
                    NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithDictionary:IMModel.message.ext];
                    [dic setObject:self.currentRedPacketDetailModel.is_finish forKey:@"is_finish"];
                    EMMessage *message = IMModel.message;
                    message.ext = dic;
                    [[EMClient sharedClient].chatManager updateMessage:message completion:^(EMMessage *aMessage, EMError *aError) {
                        [self _updateMessageStatus:message];
                    }];
                    //红包过期了
                    if ([self.currentRedPacketDetailModel.is_finish intValue] == 2) {
                    //红包过期提醒页面
                        [self receiveRedPacketOverdueWithRedPacketDetailModel:self.currentRedPacketDetailModel];
                    }else{
//红包已领取 进入领取方红包详情页面
                        MSReceiveRedPacketDetailViewController *vc =  (MSReceiveRedPacketDetailViewController *)[[self class] ms_showSBController:kSBMessageName withID:[MSReceiveRedPacketDetailViewController className]];
                        vc.model = self.currentRedPacketDetailModel;
                        vc.callBack = ^{
                            [self removeCoverView];
                        };
                        [self.navigationController pushViewController:vc animated:YES];
                    }
                }
            }
        }else{
            [MSFactory showError:model.msg];
        }
    }];
}

以上已经处理完红包各种状态的事件

以下处理自定义红包cell的布局

8、给气泡视图新增红包相关属性

MSEaseBubbleView+RedPacket.h类(MSEaseBubbleView的分类 相当于环信EaseUI中的EaseBubbleView类 依然是复制出来一份改了类名) 或者MSEaseBubbleView.h中新增以下红包字段需要的相关属性

#warning 新增的View
//redPacket views
@property (strong, nonatomic) UIImageView *redPacketIconIV;
@property (strong, nonatomic) UILabel *redPacketDetailLB;
@property (strong, nonatomic) UILabel *isReceivedRedPacket;
@property (strong, nonatomic) UILabel *RedPacketNameLB;

9、设置cell需要自定义气泡BubbleView

MSCustomRedPacketCell.m类(继承于MSEaseBaseMessageCell类 这个类就是环信EaseUI中的EaseBaseMessageCell类 我依然是复制了一份出来改了个名字)

//自定义cell需要重写这个方法 并返回YES
- (BOOL)isCustomBubbleView:(id)model
{
    return YES;
}

更新气泡约束

//重写的父类气泡刷新方法
- (void)updateCustomBubbleViewMargin:(UIEdgeInsets)bubbleMargin model:(id)model
{
#warning 分左右cell的时候 布局有区别
    //先布局气泡cell 再更新约束
    //红包240 90写死
    if (model.isSender) {
        _bubbleView.frame =
        CGRectMake(kScreenWidth - 300, 15, 240, 90);
    }else{
        _bubbleView.frame = CGRectMake(60, 15, 240, 90);
    }
    //根据红包是否领取 改变红包祝福语的布局
    [_bubbleView updateRedPacketMargin:bubbleMargin withModel:model];
    // 这里强制调用内部私有方法
//    [_bubbleView _setupRedPacketBubbleMarginConstraintsWithModel:model];
}

10、重写cell高度 115

static const CGFloat kCellHeight = 115.0f;

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

11、更新cell数据

- (void)setModel:(id)model
{
    [super setModel:model];
    
    NSDictionary *ext = [[NSDictionary alloc]initWithDictionary:model.message.ext];
    //发送了商品信息的情况
    if ([ext[@"msg_type"] isEqualToString:@"msg_red_packet"]) {
        NSDictionary *msg_infoDic = [[NSDictionary alloc]initWithDictionary:ext[@"msg_info"]];
        _bubbleView.redPacketDetailLB.text = [ext objectForKey:@"blessing_words"];
        //发送方
        if (model.isSender) {
            if ([ext[@"is_finish"] intValue] == 0) {
                _bubbleView.isReceivedRedPacket.text = @"";
                _bubbleView.isReceivedRedPacket.hidden = YES;
            }else if ([ext[@"is_finish"] intValue] == 1) {
                _bubbleView.isReceivedRedPacket.text = @"已被领取";
                _bubbleView.isReceivedRedPacket.hidden = NO;
            } else {
                _bubbleView.isReceivedRedPacket.text = @"已过期";
                _bubbleView.isReceivedRedPacket.hidden = NO;
            }
            //接收方
        }else{
            if ([ext[@"is_finish"] intValue] == 0) {
                _bubbleView.isReceivedRedPacket.text = @"";
                _bubbleView.isReceivedRedPacket.hidden = YES;
            }else if ([ext[@"is_finish"] intValue] == 1) {
                _bubbleView.isReceivedRedPacket.text = @"已领取";
                _bubbleView.isReceivedRedPacket.hidden = NO;
            }else{
                _bubbleView.isReceivedRedPacket.text = @"已过期";
                _bubbleView.isReceivedRedPacket.hidden = NO;
            }
        }
        _bubbleView.redPacketIconIV.image = [UIImage imageNamed:@"red_packet"];
    }
    
}

12、更新子视图

- (void)layoutSubviews
{
    [super layoutSubviews];
    NSDictionary *ext = [[NSDictionary alloc]initWithDictionary:self.model.message.ext];
    NSDictionary *msg_infoDic = [[NSDictionary alloc]initWithDictionary:ext[@"msg_info"]];
    NSString *imageName;
//更新气泡背景
    if (self.model.isSender) {
        if ([ext[@"is_finish"] intValue] == 1) {
            imageName = @"bubble_bg_imageView4";
        }else{
            imageName = @"bubble_bg_imageView3";
        }
    }else{
        if ([ext[@"is_finish"] intValue] == 1) {
            imageName = @"bubble_bg_imageView2";
        }else{
            imageName = @"bubble_bg_imageView";
        }
    }
    //自定义气泡拉伸位置
    UIImage *image = self.model.isSender ? [[UIImage imageNamed:imageName] stretchableImageWithLeftCapWidth:5 topCapHeight:35] :
    [[UIImage imageNamed:imageName] stretchableImageWithLeftCapWidth:20 topCapHeight:35];
    self.bubbleView.backgroundImageView.image = image;
//自定义头像大小 头像圆角
    self.avatarSize = 40.0f;
    self.avatarCornerRadius = 20.0f;
}

13、更新气泡视图约束

MSEaseBubbleView+RedPacket.m类(MSEaseBubbleView的分类 相当于环信EaseUI中的EaseBubbleView类 依然是复制出来一份改了类名)

//设置气泡视图上的控件
-(void)setupRedPacketBubbleViewWithModel:(id)model{
    //红包icon
    self.redPacketIconIV = [[UIImageView alloc]init];
    self.redPacketIconIV.translatesAutoresizingMaskIntoConstraints = NO;
    [self.backgroundImageView addSubview:self.redPacketIconIV];
    //红包title
    self.redPacketDetailLB = [[UILabel alloc] init];
    self.redPacketDetailLB.text = @"恭喜发财,大吉大利";
    self.redPacketDetailLB.font = FONT(15);
    self.redPacketDetailLB.accessibilityIdentifier = @"redPacketDetailLB";
    self.redPacketDetailLB.translatesAutoresizingMaskIntoConstraints = NO;
    self.redPacketDetailLB.backgroundColor = [UIColor clearColor];
    self.redPacketDetailLB.textColor = WhiteColor;
    [self.backgroundImageView addSubview:self.redPacketDetailLB];
    //红包领取提示
    self.isReceivedRedPacket = [[UILabel alloc] init];
    self.isReceivedRedPacket.accessibilityIdentifier = @"isReceivedRedPacket";
    self.isReceivedRedPacket.translatesAutoresizingMaskIntoConstraints = NO;
    self.isReceivedRedPacket.text = @"已领取";
    self.isReceivedRedPacket.font = FONT(12);
    self.isReceivedRedPacket.backgroundColor = [UIColor clearColor];
    self.isReceivedRedPacket.textColor = WhiteColor;
    [self.backgroundImageView addSubview:self.isReceivedRedPacket];
    //红包提示
    self.RedPacketNameLB = [[UILabel alloc] init];
    self.RedPacketNameLB.accessibilityIdentifier = @"RedPacketNameLB";
    self.RedPacketNameLB.translatesAutoresizingMaskIntoConstraints = NO;
    self.RedPacketNameLB.backgroundColor = [UIColor clearColor];
    self.RedPacketNameLB.textColor = [UIColor colorWithHexString:@"999999"];
    self.RedPacketNameLB.text = @"Kara红包";
    self.RedPacketNameLB.font = FONT(12);
    [self.backgroundImageView addSubview:self.RedPacketNameLB];
    [self _setupRedPacketBubbleMarginConstraintsWithModel:model];
    
}

更新气泡视图约束

//更新气泡视图约束
-(void)updateRedPacketMargin:(UIEdgeInsets)margin withModel:(id)model{
//    //每次进来重新更新布局 红包不同状态布局不同
//    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 _setupRedPacketBubbleMarginConstraintsWithModel:model];
}

14、设置气泡约束

根据扩展消息中的是否领取状态 更新祝福语不同的布局 并控制领取提示是否显示 isFinish == 1 祝福语靠上显示 并且显示领取提示 否则 祝福语居中显示 并且隐藏领取提示

-(void)_setupRedPacketBubbleMarginConstraintsWithModel:(id)model{
    //图片
    //上
    NSLayoutConstraint *marginTopConstraint = [NSLayoutConstraint constraintWithItem:self.redPacketIconIV attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.backgroundImageView attribute:NSLayoutAttributeTop multiplier:1.0 constant:_margin.top + 5];
    //左
    NSLayoutConstraint *marginLeftConstraint = [NSLayoutConstraint constraintWithItem:self.redPacketIconIV attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.backgroundImageView attribute:NSLayoutAttributeLeft multiplier:1.0 constant:_margin.left];
    //高度
    NSLayoutConstraint *marginHeightConstraint = [NSLayoutConstraint constraintWithItem:self.redPacketIconIV attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:40];
    //宽度
    NSLayoutConstraint *marginWidthConstraint = [NSLayoutConstraint constraintWithItem:self.redPacketIconIV attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:34];
    //祝福语
    //左边
    NSLayoutConstraint *marginLeftDetailLBConstraint = [NSLayoutConstraint constraintWithItem:self.redPacketDetailLB attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.redPacketIconIV attribute:NSLayoutAttributeRight multiplier:1.0 constant:10];
    //左边
    NSLayoutConstraint *marginRightDetailLBConstraint = [NSLayoutConstraint constraintWithItem:self.redPacketDetailLB attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.backgroundImageView attribute:NSLayoutAttributeRight multiplier:1.0 constant:_margin.right - 10];
    //当红包未被领取时 祝福语和icon竖直对齐 已领取提示隐藏
    NSLayoutConstraint *marginCenterYDetailLBConstraint = [NSLayoutConstraint constraintWithItem:self.redPacketDetailLB attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self.redPacketIconIV attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0];
    //当红包已被领取时 祝福语和icon顶部对齐 已领取提示显示
    NSLayoutConstraint *marginTopDetailLBConstraint = [NSLayoutConstraint constraintWithItem:self.redPacketDetailLB attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.redPacketIconIV attribute:NSLayoutAttributeTop multiplier:1.0 constant:0];
    //是否领取
    //左边
    NSLayoutConstraint *marginLeftIsReceviedConstraint = [NSLayoutConstraint constraintWithItem:self.isReceivedRedPacket attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.redPacketIconIV attribute:NSLayoutAttributeRight multiplier:1.0 constant:10];
    //下边
    NSLayoutConstraint *marginTBottomIsReceviedConstraint = [NSLayoutConstraint constraintWithItem:self.isReceivedRedPacket attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.redPacketIconIV attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0];
    //Kara红包
    //左边
    NSLayoutConstraint *marginLeftNameConstraint = [NSLayoutConstraint constraintWithItem:self.RedPacketNameLB attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.redPacketIconIV attribute:NSLayoutAttributeLeft multiplier:1.0 constant:0];
    //下边
    NSLayoutConstraint *marginBottomNameConstraint = [NSLayoutConstraint constraintWithItem:self.RedPacketNameLB attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.backgroundImageView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:-5];
    [self.marginConstraints removeAllObjects];
    //图片约束
    [self.marginConstraints addObject:marginTopConstraint];
    [self.marginConstraints addObject:marginLeftConstraint];
    [self.marginConstraints addObject:marginHeightConstraint];
    [self.marginConstraints addObject:marginWidthConstraint];
    //祝福语
    [self.marginConstraints addObject:marginLeftDetailLBConstraint];
    [self.marginConstraints addObject:marginRightDetailLBConstraint];
    NSDictionary *ext = [[NSDictionary alloc]initWithDictionary:model.message.ext];
    //发送了商品信息的情况
        //未领取布局
        if ([[ext objectForKey:@"is_finish"] intValue] == 0) {
            [self.marginConstraints addObject:marginCenterYDetailLBConstraint];
            //已领取红包布局
        }else{
            [self.marginConstraints addObject:marginTopDetailLBConstraint];
        }
//    }
    //是否领取
    [self.marginConstraints addObject:marginLeftIsReceviedConstraint];
    [self.marginConstraints addObject:marginTBottomIsReceviedConstraint];
    //Kara红包
    [self.marginConstraints addObject:marginLeftNameConstraint];
    [self.marginConstraints addObject:marginBottomNameConstraint];
    [self addConstraints:self.marginConstraints];
    
}

功能到此已经完成了 中间走了太多的坑 总结一下完成的流程以做笔记 也希望给看到的小伙伴一些启发吧

往后余生 愿一切安好

你可能感兴趣的:(iOS 环信 利用自定义消息(消息扩展ext)实现发红包功能)