// // XPRoomMessageView.m // xplan-ios // // Created by 冯硕 on 2021/10/11. // #import "XPRoomMessageContainerView.h" ///Third #import #import #import ///Tool #import "ThemeColor.h" #import "XPMacro.h" #import "XPRoomMessageConstant.h" #import "XPRoomMessageParser.h" #import "AccountInfoStorage.h" #import "XPRoomMiniManager.h" #import "PLTimeUtil.h" #import "ClientConfig.h" #import #import "ThemeColor+Room.h" ///Model #import "RoomInfoModel.h" #import "AttachmentModel.h" #import "RoomFaceSendInfoModel.h" ///View #import "XPRoomMessageTableViewCell.h" #import "XPRoomMessageHeaderView.h" #import "View/XPRoomMessageHeaderView.h" #import "XPRoomTrumpetView.h" NSString * const kRoomShowTopicKey = @"kRoomShowTopicKey"; @interface XPRoomMessageContainerView () ///房间的代理 @property (nonatomic,weak) id hostDelegate; ///列表 @property (nonatomic,strong) UITableView *messageTableView; ///头部 @property (nonatomic,strong) XPRoomMessageHeaderView *headerView; ///底部有新的消息 @property (nonatomic,strong) UIButton *messageTipsBtn; ///是否处于正在爬楼 @property (nonatomic,assign) BOOL isPending; ///是否是最小化进房的 @property (nonatomic,assign) BOOL isMiniEnter; ///数据源 @property (nonatomic,strong) NSMutableArray *datasource; ///临时存放消息的数组 @property (nonatomic,strong) NSMutableArray *incomingMessages; ///气泡数组 @property (nonatomic, strong) NSMutableArray *messageBubbles; ///messageView 持有这个工具类 进行数据的分发操作 TODO: 有需要在改 @property (nonatomic,strong) XPRoomMessageParser *messageParser; ///小喇叭 @property (nonatomic, strong) XPRoomTrumpetView *trumpetView; ///小喇叭队列 @property (nonatomic, strong) NSMutableArray *trumpetQueue; ///小喇叭动画定时器 @property (nonatomic, strong) dispatch_source_t trumpetTimer; ///是否是大的 只有在小游戏的时候有用 @property (nonatomic,assign) BOOL isLarge; @end @implementation XPRoomMessageContainerView - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; if (self.trumpetTimer != nil) { dispatch_source_cancel(self.trumpetTimer); } } - (instancetype)initWithDelegate:(id)delegate { self = [super init]; if (self) { self.hostDelegate = delegate; [self initSubViews]; [self initSubViewConstraints]; } return self; } #pragma mark - Response - (void)messageTipsBtnAction:(UIButton *)sender { self.isPending = NO; self.messageTipsBtn.hidden = YES; [self appendAndScrollToBottom]; } #pragma mark - Private Method - (void)initSubViews { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(addCustomMessage:) name:@"message" object:nil]; [self addSubview:self.messageTableView]; [self addSubview:self.messageTipsBtn]; self.messageTableView.tableHeaderView = self.headerView; [self addSubview:self.trumpetView]; } - (void)initSubViewConstraints { [self.messageTableView mas_makeConstraints:^(MASConstraintMaker *make) { make.left.mas_equalTo(self).offset(15); make.bottom.right.mas_equalTo(self); make.top.mas_equalTo(self.trumpetView.mas_bottom); }]; [self.messageTipsBtn mas_makeConstraints:^(MASConstraintMaker *make) { make.width.mas_equalTo(100); make.height.mas_equalTo(30); make.bottom.mas_equalTo(self.mas_bottom).offset(-5); make.left.mas_equalTo(self); }]; [self.trumpetView mas_makeConstraints:^(MASConstraintMaker *make) { make.top.mas_equalTo(self); make.left.mas_equalTo(15); make.right.mas_equalTo(0); make.height.mas_equalTo(0); }]; } ///是否是当前房间 - (BOOL)isCurrentRoom:(NSString *)sessionId { if ([sessionId isEqualToString:[NSString stringWithFormat:@"%ld", self.hostDelegate.getRoomInfo.roomId]]) { return YES; } return NO; } #pragma mark - 添加数据并且做自动滚动 ///添加信息 - (void)addRoomMessage:(NIMMessage *)message { [self.incomingMessages addObject:message]; if (!self.isMiniEnter) {/// 最小化进房的话 不需要重新保存 if (self.hostDelegate.getRoomInfo.isCloseScreen) { NIMCustomObject *obj = (NIMCustomObject *)message.messageObject; if (obj.attachment != nil && [obj.attachment isKindOfClass:[AttachmentModel class]]) { AttachmentModel *attachment = (AttachmentModel *)obj.attachment; if (attachment.first == CustomMessageType_Update_RoomInfo && attachment.second == Custom_Message_Sub_Update_RoomInfo_MessageState){ [[XPRoomMiniManager shareManager] saveRoomMessage:message]; } } } else { [[XPRoomMiniManager shareManager] saveRoomMessage:message]; } } if (self.isPending) { self.messageTipsBtn.hidden = NO; } else { [self appendAndScrollToBottom]; } } ///追加数据源 - (void)appendAndScrollToBottom { if (self.incomingMessages.count < 1) { return; } if (self.datasource.count > kRoomMessageMaxLength) { NSIndexSet *set = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, kRoomMessageMaxLength/2)]; NSArray *needRemoveMsgArray = [self.datasource objectsAtIndexes:set]; [self.datasource removeObjectsInArray:needRemoveMsgArray]; [self.messageBubbles removeObjectsInArray:needRemoveMsgArray]; } // 执行插入 NSMutableArray *indexPaths = [NSMutableArray array]; for (NIMMessage *item in self.incomingMessages) { [self.datasource addObject:[self.messageParser parseMessageAttribute:item]]; [self.messageBubbles addObject:[self.messageParser parseMessageBubble:item]]; [indexPaths addObject:[NSIndexPath indexPathForRow:self.datasource.count - 1 inSection:0]]; } [self.incomingMessages removeAllObjects]; [self.messageTableView reloadData]; //执行插入动画并滚动 [self scrollToBottom:YES]; } ///执行插入动画并滚动 - (void)scrollToBottom:(BOOL)animated { NSInteger s = [self.messageTableView numberOfSections]; //有多少组 if (s<1) return; NSInteger r = [self.messageTableView numberOfRowsInSection:s-1]; //最后一组行 if (r<1) return; NSIndexPath *ip = [NSIndexPath indexPathForRow:r-1 inSection:s-1]; //取最后一行数据 [self.messageTableView scrollToRowAtIndexPath:ip atScrollPosition:UITableViewScrollPositionBottom animated:animated]; //滚动到最后一行 } ///自定义消息 是否可以加到 公屏 需要自己维护 - (BOOL)isCanDisplayMessage:(NIMMessage *)message { NIMCustomObject *obj = (NIMCustomObject *)message.messageObject; if (obj.attachment != nil && [obj.attachment isKindOfClass:[AttachmentModel class]]) { AttachmentModel *attachment = (AttachmentModel *)obj.attachment; if (attachment.first == CustomMessageType_Face && attachment.second == Custom_Message_Sub_Face_Send) { if ([attachment.data[@"data"] isKindOfClass:[NSArray class]]) { NSArray * array = [RoomFaceSendInfoModel modelsWithArray:attachment.data[@"data"]]; for (int i = 0; i< array.count; i++) { RoomFaceSendInfoModel * sendInfo = [array objectAtIndex:i]; if (sendInfo.resultIndexes.count <=0) { return NO; } } } } return [[[self supportMessageDic] objectForKey:@(attachment.first)] containsObject:@(attachment.second)]; } return NO; } - (NSDictionary *)supportMessageDic { return @{ @(CustomMessageType_AllMicroSend): [NSSet setWithObjects: @(Custom_Message_Sub_AllMicroSend), @(Custom_Message_Sub_AllMicroLuckySend), @(Custom_Message_Sub_AllBatchSend), @(Custom_Message_Sub_AllBatchMicroLuckySend), nil], @(CustomMessageType_Gift): [NSSet setWithObjects: @(Custom_Message_Sub_Gift_Send), @(Custom_Message_Sub_Gift_LuckySend), nil], @(CustomMessageType_Room_Tip): [NSSet setWithObjects: @(Custom_Message_Sub_Room_Tip_ShareRoom), @(Custom_Message_Sub_Room_Tip_Attention_Owner), nil], @(CustomMessageType_Kick_User): [NSSet setWithObjects: @(Custom_Message_Sub_Kick_BeKicked), @(Custom_Message_Sub_Kick_BlackList), nil], @(CustomMessageType_Queue): [NSSet setWithObjects: @(Custom_Message_Sub_Queue_Kick), nil], @(CustomMessageType_Candy_Tree): [NSSet setWithObjects: @(Custom_Message_Sub_Candy_Tree_Me), @(Custom_Message_Sub_Candy_Tree_InRoom), @(Custom_Message_Sub_Candy_Tree_AllRoom), @(Custom_Message_Sub_Candy_Tree_AllRoom_Notify), @(Custom_Message_Sub_Candy_Tree_InRoom_NeedAllMicSend), nil], @(CustomMessageType_Arrange_Mic): [NSSet setWithObjects: @(Custom_Message_Sub_Arrange_Mic_Mode_Open), @(Custom_Message_Sub_Arrange_Mic_Mode_Close), @(Custom_Message_Sub_Arrange_Mic_Free_Mic_Open), @(Custom_Message_Sub_Arrange_Mic_Free_Mic_Close), nil], @(CustomMessageType_Update_RoomInfo): [NSSet setWithObjects: @(Custom_Message_Sub_Update_RoomInfo_MessageState), @(Custom_Message_Sub_Update_RoomInfo_AnimateEffect), nil], @(CustomMessageType_Collection_Room): [NSSet setWithObjects: @(Custom_Message_Sub_Collect_Room_Tips), nil], @(CustomMessageType_RoomPlay_Dating): [NSSet setWithObjects: @(Custom_Message_Sub_Room_Play_Dating_Pick_Heart), @(Custom_Message_Sub_Room_Play_Dating_Result_Mutual), @(Custom_Message_Sub_Room_Play_Dating_Result_Not_Mutual), nil], @(CustomMessageType_Noble_VIP): [NSSet setWithObjects: @(Custom_Message_Sub_Room_Open_Noble_VIP), @(Custom_Message_Sub_Room_Noble_LevelUp), @(Custom_Message_Sub_AllRoom_Noble_LevelUp_Suspend), nil], @(CustomMessageType_Face): [NSSet setWithObjects: @(Custom_Message_Sub_Face_Send), nil], @(CustomMessageType_Anchor_FansTeam): [NSSet setWithObjects: @(Custom_Message_Sub_FansTeam_Open_Success), @(Custom_Message_Sub_FansTeam_Open_Fail), @(Custom_Message_Sub_FansTeam_Join_Success), @(Custom_Message_Sub_FansTeam_Out_Success), nil], }; } - (void)addCustomMessage:(NSNotification *)notification { self.isMiniEnter = NO; if (self.hostDelegate.getRoomInfo.isCloseScreen) {return;} NIMMessage * message = notification.object; [self addRoomMessage:message]; } ///用户进入房间显示 房间话题 - (void)createUserEnterRoomAddRoomtopicMessage { if ([ClientConfig shareConfig].configInfo.appStoreAuditNoticeVersion == YES) { return; } RoomInfoModel * roomInfo = self.hostDelegate.getRoomInfo; if (roomInfo.uid == [AccountInfoStorage instance].getUid.integerValue) {return;} NSString * key = [NSString stringWithFormat:@"%@_%@_%ld", kRoomShowTopicKey, [AccountInfoStorage instance].getUid, roomInfo.uid]; NSDate * oldDate = [[NSUserDefaults standardUserDefaults] valueForKey:key]; NSDate * date = [NSDate date]; if (roomInfo.introduction.length > 0) { if (oldDate) { NSDateComponents *compons = [PLTimeUtil compareTwoDate:date secondDate:[NSDate date]]; if (ABS(compons.year) > 0 || ABS(compons.month) > 0 || ABS(compons.day) > 0) { NIMMessage * message = [[NIMMessage alloc] init]; NSString * content = [NSString stringWithFormat:@"[房间公告] \n %@", roomInfo.introduction]; message.text = content; message.localExt = @{@"isRoomTopic": @(NO)}; [message setValue:@(NIMMessageTypeTip) forKey:@"messageType"]; [message setValue:[NIMSession session:[NSString stringWithFormat:@"%ld", roomInfo.roomId] type:NIMSessionTypeChatroom] forKey:@"session"]; [self addRoomMessage:message]; [[NSUserDefaults standardUserDefaults] setValue:@(YES) forKey:key]; [[NSUserDefaults standardUserDefaults] synchronize]; } } else { NIMMessage * message = [[NIMMessage alloc] init]; NSString * content = [NSString stringWithFormat:@"[房间公告] \n %@", roomInfo.introduction]; message.text = content; message.localExt = @{@"isRoomTopic": @(NO)}; [message setValue:@(NIMMessageTypeTip) forKey:@"messageType"]; [message setValue:[NIMSession session:[NSString stringWithFormat:@"%ld", roomInfo.roomId] type:NIMSessionTypeChatroom] forKey:@"session"]; [self addRoomMessage:message]; [[NSUserDefaults standardUserDefaults] setValue:@(YES) forKey:key]; [[NSUserDefaults standardUserDefaults] synchronize]; } } NIMMessage * message = [[NIMMessage alloc] init]; message.text = @"可点击查看本房间公告"; message.localExt = @{@"isRoomTopic": @(YES)}; [message setValue:@(NIMMessageTypeTip) forKey:@"messageType"]; [message setValue:[NIMSession session:[NSString stringWithFormat:@"%ld", roomInfo.roomId] type:NIMSessionTypeChatroom] forKey:@"session"]; [self addRoomMessage:message]; } #pragma mark - RoomGuestDelegate - (void)handleNIMCustomMessage:(NIMMessage *)message { self.isMiniEnter = NO; NIMCustomObject *obj = (NIMCustomObject *)message.messageObject; if (obj.attachment != nil && [obj.attachment isKindOfClass:[AttachmentModel class]]) { AttachmentModel *attachment = (AttachmentModel *)obj.attachment; if (attachment.first == CustomMessageType_Update_RoomInfo && attachment.second == Custom_Message_Sub_Update_RoomInfo_MessageState) { [self.datasource removeAllObjects]; [self.incomingMessages removeAllObjects]; [self.messageBubbles removeAllObjects]; [[XPRoomMiniManager shareManager] resetLocalMessage]; [self addRoomMessage:message]; return; } else if (attachment.first == CustomMessageType_Noble_VIP && attachment.second == Custom_Message_Sub_Room_Trumpet) { if (self.trumpetQueue.count) { [self.trumpetQueue addObject:attachment.data]; } else { [self.trumpetQueue addObject:attachment.data]; __block NSInteger time = 5.0; //倒计时时间 if (_trumpetTimer != nil) { dispatch_source_cancel(_trumpetTimer); } dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); _trumpetTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue); dispatch_source_set_timer(_trumpetTimer,dispatch_walltime(NULL, 0),time*NSEC_PER_SEC, 0); //每秒执行 dispatch_source_set_event_handler(_trumpetTimer, ^{ if (self.trumpetQueue.count) { dispatch_sync(dispatch_get_main_queue(), ^{ [self createTrumpetAnimation:self.trumpetQueue.firstObject]; [self.trumpetQueue removeObjectAtIndex:0]; }); } else { dispatch_sync(dispatch_get_main_queue(), ^{ self.trumpetView.hidden = YES; [self.trumpetView mas_updateConstraints:^(MASConstraintMaker *make) { make.height.mas_equalTo(0); }]; [self.messageTableView mas_updateConstraints:^(MASConstraintMaker *make) { make.top.mas_equalTo(self.trumpetView.mas_bottom); }]; }); if (self->_trumpetTimer != nil) { dispatch_source_cancel(self->_trumpetTimer); } } }); dispatch_resume(_trumpetTimer); } return; } } if (self.hostDelegate.getRoomInfo.isCloseScreen) { return; } if ([self isCanDisplayMessage:message]) { [self addRoomMessage:message]; } } - (void)handleNIMNotificationMessage:(NIMMessage *)message { self.isMiniEnter = NO; NIMNotificationObject *notiMsg = (NIMNotificationObject *)message.messageObject; NIMChatroomNotificationContent *content = (NIMChatroomNotificationContent *)notiMsg.content; RoomInfoModel * roomInfo = self.hostDelegate.getRoomInfo; if (content.eventType == NIMChatroomEventTypeEnter) { if (roomInfo.isCloseScreen) { AttachmentModel *attachement = [[AttachmentModel alloc]init]; attachement.first = CustomMessageType_Update_RoomInfo; attachement.second = Custom_Message_Sub_Update_RoomInfo_MessageState; attachement.data = @{@"roomInfo":self.hostDelegate.getRoomInfo.model2dictionary}; NIMMessage *message = [[NIMMessage alloc]init]; NIMCustomObject *object = [[NIMCustomObject alloc] init]; object.attachment = attachement; message.messageObject = object; [self addRoomMessage:message]; return; } else { [self addRoomMessage:message]; NIMChatroomNotificationMember *member = content.targets[0]; if (member.userId.integerValue == [AccountInfoStorage instance].getUid.integerValue) { if (!roomInfo.hasAnimationEffect) { [self roomInfoNoGiftAnimationMessage:message]; } [self createUserEnterRoomAddRoomtopicMessage]; } } } else if(content.eventType == NIMChatroomEventTypeInfoUpdated) { if (roomInfo.isCloseScreen) {return;} if (roomInfo.datingState == RoomDatingStateChangeType_Open) { [self addRoomMessage:message]; } } } - (void)handleNIMTextMessage:(NIMMessage *)message { self.isMiniEnter = NO; if (self.hostDelegate.getRoomInfo.isCloseScreen) {return;} [self addRoomMessage:message]; } - (void)roomInfoNoGiftAnimationMessage:(NIMMessage *)message { self.isMiniEnter = NO; AttachmentModel *attachement = [[AttachmentModel alloc]init]; attachement.first = CustomMessageType_Update_RoomInfo; attachement.second = Custom_Message_Sub_Update_RoomInfo_AnimateEffect; NIMMessage *tempMessage = [[NIMMessage alloc]init]; NIMCustomObject *customObject = [[NIMCustomObject alloc]init]; customObject.attachment = attachement; tempMessage.messageObject = customObject; [self addRoomMessage:tempMessage]; } - (void)onRoomMiniEntered { self.isMiniEnter = YES; NSArray * temArray = [XPRoomMiniManager shareManager].getLocalCurrentRoomMessage; for (int i = 0; i< temArray.count; i++) { NIMMessage * message = [temArray objectAtIndex:i]; [self addRoomMessage:message]; } } - (void)onRoomEntered { [[XPRoomMiniManager shareManager] resetLocalMessage]; self.headerView.bubbleColor = self.hostDelegate.getRoomInfo.type == RoomType_MiniGame ? [UIColor colorWithWhite:1 alpha:0.2] : [ThemeColor messageBubbleColor]; } - (void)onRoomUpdate { ///改变公屏的背景样式 if (self.hostDelegate.getRoomInfo.hadChangeRoomType) { self.headerView.bubbleColor = self.hostDelegate.getRoomInfo.type == RoomType_MiniGame ? [UIColor colorWithWhite:1 alpha:0.2] : [ThemeColor messageBubbleColor]; [self.messageTableView reloadData]; } } #pragma mark - ScrollViewDelegate - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView { // 手动拖拽开始 self.isPending = YES; } - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate { // 手动拖拽结束(decelerate:0松手时静止;1松手时还在运动,会触发DidEndDecelerating方法) if (!decelerate) { [self finishDraggingWith:scrollView]; } } - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { // 静止后触发(手动) [self finishDraggingWith:scrollView]; } - (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView { if (!self.isPending && self.incomingMessages.count <= 0) { [self scrollToBottom:YES]; } } /** 手动拖拽动作彻底完成(减速到零) */ - (void)finishDraggingWith:(UIScrollView *)scrollView { CGFloat contentSizeH = scrollView.contentSize.height; CGFloat contentOffsetY = scrollView.contentOffset.y; CGFloat sizeH = scrollView.frame.size.height; self.isPending = contentSizeH - contentOffsetY - sizeH > 20.0; if (!self.isPending) { self.messageTipsBtn.hidden = YES; if (self.incomingMessages.count > 0) { [self appendAndScrollToBottom]; } } } #pragma mark - UITableViewDelegate And UITableViewDataSource - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return self.datasource.count; } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { NSAttributedString* attr = [self.datasource objectAtIndex:indexPath.row]; CGSize maxSize = CGSizeMake(kRoomMessageMaxWidth - 24, MAXFLOAT); YYTextContainer *container = [YYTextContainer containerWithSize:maxSize]; container.maximumNumberOfRows = 0; YYTextLayout *layout = [YYTextLayout layoutWithContainer:container text:attr]; return layout.textBoundingSize.height + kRoomMessageTextSpaceHeight * 2 + 10; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { XPRoomMessageTableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([XPRoomMessageTableViewCell class])]; if (cell == nil) { cell = [[XPRoomMessageTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:NSStringFromClass([XPRoomMessageTableViewCell class])]; } cell.delegate = self; NSAttributedString* attr = [self.datasource objectAtIndex:indexPath.row]; NSString *bubbleStr = [self.messageBubbles objectAtIndex:indexPath.row]; cell.bubbleImageUrl = bubbleStr; cell.roomType = self.hostDelegate.getRoomInfo.type; cell.attributedString = attr; return cell; } - (void)createTrumpetAnimation:(NSDictionary *)attatchment { self.trumpetView.data = attatchment; self.trumpetView.hidden = NO; [self.trumpetView mas_updateConstraints:^(MASConstraintMaker *make) { make.height.mas_equalTo(32); }]; [self.messageTableView mas_updateConstraints:^(MASConstraintMaker *make) { make.top.mas_equalTo(self.trumpetView.mas_bottom).mas_offset(4); }]; POPBasicAnimation *animation2 = [POPBasicAnimation animationWithPropertyNamed:kPOPViewFrame]; animation2.beginTime = CACurrentMediaTime(); animation2.duration = 0.1; CGFloat width = self.frame.size.width - 15; CGFloat height = 32; animation2.fromValue = [NSValue valueWithCGRect:CGRectMake(0, 0, width, height)]; animation2.toValue = [NSValue valueWithCGRect:CGRectMake(0, -height/2, width, height)]; animation2.removedOnCompletion = NO; animation2.repeatCount = 1; POPBasicAnimation *animation3 = [POPBasicAnimation animationWithPropertyNamed:kPOPLayerOpacity]; animation3.duration = 0.1; animation3.beginTime = CACurrentMediaTime(); animation3.fromValue = @1; animation3.toValue = @0; animation3.repeatCount = 1; animation3.removedOnCompletion = NO; [animation2 setCompletionBlock:^(POPAnimation *anim, BOOL finished) { if (finished) { POPBasicAnimation *animation2 = [POPBasicAnimation animationWithPropertyNamed:kPOPViewFrame]; animation2.beginTime = CACurrentMediaTime(); animation2.duration = 0.1; CGFloat width = self.frame.size.width - 15; CGFloat height = 32; animation2.fromValue = [NSValue valueWithCGRect:CGRectMake(0, height/2, width, height)]; animation2.toValue = [NSValue valueWithCGRect:CGRectMake(0, 0, width, height)]; animation2.removedOnCompletion = NO; animation2.repeatCount = 1; POPBasicAnimation *animation3 = [POPBasicAnimation animationWithPropertyNamed:kPOPLayerOpacity]; animation3.duration = 0.1; animation3.beginTime = CACurrentMediaTime(); animation3.fromValue = @0; animation3.toValue = @1; animation3.repeatCount = 1; animation3.removedOnCompletion = NO; [self.trumpetView.mainView.layer pop_addAnimation:animation2 forKey:@"animation4"]; [self.trumpetView.mainView.layer pop_addAnimation:animation3 forKey:@"animation5"]; } }]; [self.trumpetView.mainView.layer pop_addAnimation:animation2 forKey:@"animation2"]; [self.trumpetView.mainView.layer pop_addAnimation:animation3 forKey:@"animation3"]; } #pragma mark - XPRoomMessageTableViewCellDelegate - (void)xPRoomMessageTableViewCellDidTapEmpty:(XPRoomMessageTableViewCell *)view { if (self.hostDelegate.getRoomInfo.type == RoomType_MiniGame) { self.isLarge = !self.isLarge; CGFloat height = self.isLarge ? 200 : 80; [self mas_updateConstraints:^(MASConstraintMaker *make) { make.height.mas_equalTo(height); }]; } } #pragma mark - Getters And Setters - (UITableView *)messageTableView { if (!_messageTableView) { _messageTableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain]; _messageTableView.delegate = self; _messageTableView.dataSource = self; _messageTableView.tableFooterView = [UIView new]; _messageTableView.separatorStyle = UITableViewCellSeparatorStyleNone; _messageTableView.backgroundColor = [UIColor clearColor]; _messageTableView.showsVerticalScrollIndicator = NO; if (@available(iOS 11.0, *)) { _messageTableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; } [_messageTableView registerClass:[XPRoomMessageTableViewCell class] forCellReuseIdentifier:NSStringFromClass([XPRoomMessageTableViewCell class])]; } return _messageTableView; } - (XPRoomMessageHeaderView *)headerView { if (!_headerView) { _headerView = [[XPRoomMessageHeaderView alloc] init]; } return _headerView; } - (UIButton *)messageTipsBtn { if (!_messageTipsBtn) { _messageTipsBtn = [UIButton buttonWithType:UIButtonTypeCustom]; [_messageTipsBtn setTitle:@"底部有新消息" forState:UIControlStateNormal]; [_messageTipsBtn setTitleColor:[ThemeColor appMainColor] forState:UIControlStateNormal]; _messageTipsBtn.layer.cornerRadius = 15.0; _messageTipsBtn.layer.masksToBounds = YES; _messageTipsBtn.titleLabel.font = [UIFont systemFontOfSize:12.0]; _messageTipsBtn.backgroundColor = [UIColor whiteColor]; [_messageTipsBtn addTarget:self action:@selector(messageTipsBtnAction:) forControlEvents:UIControlEventTouchUpInside]; _messageTipsBtn.hidden = YES; } return _messageTipsBtn; } - (NSMutableArray *)datasource { if (!_datasource) { _datasource = [NSMutableArray array]; } return _datasource; } - (NSMutableArray *)incomingMessages { if (!_incomingMessages) { _incomingMessages = [NSMutableArray array]; } return _incomingMessages; } - (NSMutableArray *)messageBubbles { if (!_messageBubbles) { _messageBubbles = [NSMutableArray array]; } return _messageBubbles; } - (XPRoomMessageParser *)messageParser { if (!_messageParser) { _messageParser = [[XPRoomMessageParser alloc] init]; _messageParser.hostDelegate = self.hostDelegate; } return _messageParser; } - (XPRoomTrumpetView *)trumpetView { if (!_trumpetView) { _trumpetView = [[XPRoomTrumpetView alloc] init]; _trumpetView.hidden = YES; } return _trumpetView; } - (NSMutableArray *)trumpetQueue { if (!_trumpetQueue) { _trumpetQueue = [NSMutableArray array]; } return _trumpetQueue; } @end