Files
peko-ios/YuMi/Modules/YMMessage/View/Session/SessionViewController.m
2024-02-21 10:18:59 +08:00

1171 lines
45 KiB
Objective-C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// SessionViewController.m
// YUMI
//
// Created by zu on 2021/11/28.
//
#import "SessionViewController.h"
#import <Masonry/Masonry.h>
#import <IQKeyboardManager/IQKeyboardManager.h>
#import <TZImagePickerController/TZImagePickerController.h>
#import <MJRefresh/MJRefresh.h>
#import <Photos/Photos.h>
///Tool
#import "XCCurrentVCStackManager.h"
#import "NIMMessageMaker.h"
#import "YUMIMacroUitls.h"
#import "UITableView+NIMScrollToBottom.h"
#import "DJDKMIMOMColor.h"
#import "NSArray+Safe.h"
#import "QEmotionHelper.h"
#import "QKeyboardManager.h"
#import "YYUtility.h"
#import "TTPopup.h"
#import "AccountInfoStorage.h"
#import "NSDate+DateUtils.h"
#import "PLTimeUtil.h"
#import "StatisticsServiceHelper.h"
#import "NIMMessageUtils.h"
#import "ClientConfig.h"
///Model
#import "RoomInfoModel.h"
#import "UserInfoModel.h"
#import "MessageMenuModel.h"
#import "SessionRiskCache.h"
#import "QPhotoImageModel.h"
#import "AttachmentModel.h"
#import "MessageBaseModel.h"
#import "MessageTextModel.h"
#import "MessageAudioModel.h"
#import "MessageTimeModel.h"
#import "MessageImageModel.h"
#import "MessageUnSupportModel.h"
#import "MessageGiftModel.h"
#import "PIMessageContentServiceReplyModel.h"
#import "MessageTextClickModel.h"
#import "MessageGuildModel.h"
#import "MessageOpenLiveModel.h"
#import "MessageRedPacketModel.h"
#import "MessageMonentsAutoModel.h"
#import "MessageMonentsModel.h"
#import "MessageRiskAlertModel.h"
#import "MessageFindNewGreetModel.h"
#import "MessageSkillCardModel.h"
#import "MessageTweetModel.h"
#import "MessageLevelUpgradeModel.h"
#import "MessageOpenLiveModel.h"
#import "MessageRevokeModel.h"
#import "MessageTipsModel.h"
#import "MessageTreasureFairyModel.h"
///View
#import "XPMineUserInfoViewController.h"
#import "XPMineSimpleUserInfoViewController.h"
#import "XPRoomViewController.h"
#import "RoomHostDelegate.h"
#import "MessageCell.h"
#import "SessionChatLimitView.h"
#import "XPSendGiftView.h"
#import "SessionNavView.h"
#import "SessionInfoViewController.h"
#import "SessionRiskView.h"
#import "QInputBarView.h"
#import "QKeyboardManager.h"
#import "QEmotionBoardView.h"
#import "QinputPhotoView.h"
#import "SessionUserInfoTableViewCell.h"
///P
#import "MessagePresenter.h"
#import "MessageProtocol.h"
#import "Api+Message.h"
@interface SessionViewController ()<MessageProtocol, UITableViewDelegate, UITableViewDataSource, NIMChatManagerDelegate, NIMConversationManagerDelegate, NIMMediaManagerDelegate, MessageCellDelegate, TZImagePickerControllerDelegate, SessionNavViewDelegate, SessionRiskViewDelegate,QInputBarViewDelegate, QInputBarViewDataSource,InputBoardDataSource ,InputBoardDelegate , QEmotionBoardViewDelegate, QinputPhotoViewDelegate, SessionUserInfoTableViewCellDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate>
@property (nonatomic, strong) NIMSession * session;
@property (nonatomic, strong) NSMutableArray<MessageBaseModel *> * messages;
///导航栏
@property (nonatomic,strong) SessionNavView *sessionNavView;
@property (nonatomic, strong) UITableView * sessionTableView;
@property (nonatomic, strong) UserInfoModel *userInfo;
@property (nonatomic, strong) UserInfoModel *detailUserInfo;
///最后的一条消息
@property (nonatomic,strong) NIMMessage *lastMessage;
///私聊风险提示
@property (nonatomic,strong) SessionRiskView *riskAlertView;
@property(nonatomic,strong)QInputBarView *inputBarView;
@property(nonatomic,strong)QKeyboardManager *keyboardManager;
///相册
@property (nonatomic,strong) QinputPhotoView *photoView;
///
@property (nonatomic,strong) NSArray *phototArray;
@end
@implementation SessionViewController
- (BOOL)isHiddenNavBar {
return YES;
}
- (void)dealloc {
[[NIMSDK sharedSDK].chatManager removeDelegate:self];
[[NIMSDK sharedSDK].conversationManager removeDelegate:self];
[[NIMSDK sharedSDK].mediaManager removeDelegate:self];
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (MessagePresenter *)createPresenter {
return [[MessagePresenter alloc] init];
}
- (instancetype)initWithSession:(NIMSession *)session {
self = [super init];
if (self) {
_session = session;
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
[self initViews];
[self initLayout];
[IQKeyboardManager sharedManager].enable = NO;
[IQKeyboardManager sharedManager].enableAutoToolbar = NO;
[self initHeaderAndFooterRrfresh];
[[NIMSDK sharedSDK].chatManager addDelegate:self];
[[NIMSDK sharedSDK].conversationManager addDelegate:self];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.presenter getFansLike:self.session.sessionId];
[self.presenter getUserInfoWithUid:self.session.sessionId];
}
- (void)initHeaderAndFooterRrfresh {
MJRefreshNormalHeader *header = [MJRefreshNormalHeader headerWithRefreshingTarget:self refreshingAction:@selector(headerRefresh)];
header.stateLabel.font = [UIFont systemFontOfSize:10.0];
header.lastUpdatedTimeLabel.font = [UIFont systemFontOfSize:10.0];
header.stateLabel.textColor = [DJDKMIMOMColor secondTextColor];
header.lastUpdatedTimeLabel.textColor = [DJDKMIMOMColor secondTextColor];
self.sessionTableView.mj_header = header;
[self headerRefresh];
[self initData];
}
- (void)headerRefresh {
if (self.messages.count > 0) {
MessageBaseModel * model = self.messages.firstObject;
[[[NIMSDK sharedSDK] conversationManager] messagesInSession:self.session message:model.message limit:20 completion:^(NSError * _Nullable error, NSArray<NIMMessage *> * _Nullable messages) {
[self.sessionTableView.mj_header endRefreshing];
if (error == nil && messages.count > 0) {
for (int i = ((int)messages.count -1); i >= 0; i--) {
NIMMessage * message = [messages safeObjectAtIndex1:i];
MessageBaseModel * model = [self modeTransformMessage:message];
[self.messages insertObject:model atIndex:0];
if ((i -1) > 0) {
NIMMessage * message1 = [messages safeObjectAtIndex1:i -1];
CGFloat dur = message.timestamp - message1.timestamp;
if (dur / 60 > 5) {
MessageBaseModel * timeModel = [self createTimeMessage:message];
[self.messages insertObject:timeModel atIndex:0];
}
}
}
}
[self.sessionTableView reloadData];
}];
} else {
[[[NIMSDK sharedSDK] conversationManager] messagesInSession:self.session message:nil limit:20 completion:^(NSError * _Nullable error, NSArray<NIMMessage *> * _Nullable messages) {
[self.sessionTableView.mj_header endRefreshing];
if (error == nil) {
for (int i = 0; i < messages.count; i++) {
NIMMessage * message = [messages safeObjectAtIndex1:i];
MessageBaseModel * model = [self modeTransformMessage:message];
if ((i + 1) < messages.count) {
NIMMessage * message1 = [messages safeObjectAtIndex1:i + 1];
CGFloat dur = message1.timestamp - message.timestamp;
if (dur / 60 > 5) {
MessageBaseModel * timeModel = [self createTimeMessage:message];
[self.messages addObject:timeModel];
}
}
[self.messages addObject:model];
}
}
[self.sessionTableView reloadData];
[self.sessionTableView nim_scrollToBottom:YES];
}];
}
}
#pragma mark - 提前加载相册中的图片
- (void)loadAlbumPhotos {
@kWeakify(self);
[YYUtility checkAssetsLibrayAvailable:^{
} denied:^{
} restriction:^{
}];
}
#pragma mark - cell的样式
- (MessageBaseModel *)modeTransformMessage:(NIMMessage *)message {
MessageBaseModel * model;
switch (message.messageType) {
case NIMMessageTypeText:
model = [[MessageTextModel alloc] initWithMessage:message];
break;
case NIMMessageTypeAudio:
model = [[MessageAudioModel alloc] initWithMessage:message];
break;
case NIMMessageTypeImage:
model = [[MessageImageModel alloc] initWithMessage:message];
break;
case NIMMessageTypeTip:
model = [[MessageTipsModel alloc] initWithMessage:message];
break;
case NIMMessageTypeCustom:
model = [self modelTransformCustomMessage:message];
break;
default:
model = [[MessageUnSupportModel alloc] initWithMessage:message];
break;
break;
}
return model;
}
- (MessageBaseModel *)modelTransformCustomMessage:(NIMMessage *)message {
MessageBaseModel * model;
NIMCustomObject *obj = (NIMCustomObject *)message.messageObject;
AttachmentModel *attachment = (AttachmentModel *)obj.attachment;
if (attachment.first == CustomMessageType_Gift && attachment.second == Custom_Message_Sub_Gift_Send) {
model = [[MessageGiftModel alloc] initWithMessage:message];
} else if(attachment.first == CustomMessageType_Secretary) {
model = [[MessageTextClickModel alloc] initWithMessage:message];
} else if(attachment.first == CustomMessageType_Hall) {
model = [[MessageGuildModel alloc] initWithMessage:message];
} else if(attachment.first == CustomMessageType_Member_Online && attachment.second == Custom_Message_Type_Attention_Member_Online) {
model = [[MessageOpenLiveModel alloc] initWithMessage:message];
} else if(attachment.first == CustomMessageType_Application_Share && attachment.second == Custom_Message_Sub_Application_Share_Room) {
model = [[MessageOpenLiveModel alloc] initWithMessage:message];
} else if(attachment.first == CustomMessageType_User_UpGrade && (attachment.second == Custom_Message_Sub_User_UpGrade_Charm || attachment.second == Custom_Message_Sub_User_UpGrade_Exper)) {
model = [[MessageLevelUpgradeModel alloc] initWithMessage:message];
} else if(attachment.first == CustomMessageType_Tweet && attachment.second == Custom_Message_Sub_Tweet_News) {
model = [[MessageTweetModel alloc] initWithMessage:message];
} else if(attachment.first == CustomMessageType_Skill_Card) {
model = [[MessageSkillCardModel alloc] initWithMessage:message];
} else if(attachment.first == CustomMessageType_FindNew){
model = [[MessageFindNewGreetModel alloc] initWithMessage:message];
} else if(attachment.first == CustomMessageType_Chat_Risk_Alert) {
model = [[MessageRiskAlertModel alloc] initWithMessage:message];
}else if(attachment.first == CustomMessageType_Monents && attachment.second == Custom_Message_Sub_Monents_Share) {
model = [[MessageMonentsModel alloc] initWithMessage:message];
}else if(attachment.first == CustomMessageType_Monents && (attachment.second == Custom_Message_Sub_Monents_Approved | attachment.second == Custom_Message_Sub_Monents_Ban_Delete)) {
model = [[MessageMonentsAutoModel alloc] initWithMessage:message];
} else if(attachment.first == CustomMessageType_Message_Handle && attachment.second == Custom_Message_Sub_Message_Handle_Content) {
model = [[MessageMonentsAutoModel alloc] initWithMessage:message];
} else if (attachment.first == CustomMessageType_RedPacket && attachment.second == Custom_Message_Sub_AllDiamandRedPacket) {
model = [[MessageRedPacketModel alloc] initWithMessage:message];
}else if (attachment.first == CustomMessageType_Treasure_Fairy && (attachment.second == Custom_Message_Sub_Treasure_Fairy_Ask_Fairy || attachment.second == Custom_Message_Sub_Treasure_Fairy_Send_Fairy)) {
model = [[MessageTreasureFairyModel alloc] initWithMessage:message];
}else if(attachment.first == CustomMessageType_Service_Reply){
model = [[PIMessageContentServiceReplyModel alloc]initWithMessage:message];
}else {
model = [[MessageUnSupportModel alloc] initWithMessage:message];
}
return model;
}
- (UINavigationController *)getKeyWindowNav {
if ([XCCurrentVCStackManager shareManager].getCurrentVC) {
return [XCCurrentVCStackManager shareManager].getCurrentVC.navigationController;
}
return self.navigationController;
}
- (MessageBaseModel *)createTimeMessage:(NIMMessage *)message {
MessageTimeModel * timeModel = [[MessageTimeModel alloc] initWithMessage:message];
timeModel.time = [self timestrToTimeSecond:[NSString stringWithFormat:@"%f", message.timestamp]];
return timeModel;
}
- (NSString *)timestrToTimeSecond:(NSString *)timeStr {//timestr 豪秒
NSTimeInterval interval = [timeStr doubleValue];
NSDate *date = [NSDate dateWithTimeIntervalSince1970:interval];
return [NSDate stringFromDate:date];
}
- (void)addTimeMessage:(NIMMessage *)message {
if (self.messages.count > 0) {
NIMMessage * lastMessage = self.messages.lastObject.message;
CGFloat dur = message.timestamp - lastMessage.timestamp;
if (dur / 60 > 5) {
NIMMessage * newMessage = [[NIMMessage alloc] init];
newMessage.timestamp = message.timestamp;
[newMessage setValue:self.session forKey:@"session"];
MessageBaseModel * timeModel = [self createTimeMessage:newMessage];
[self.messages addObject:timeModel];
}
}
}
- (void)addRevokeMessage:(NIMMessage *)message title:(NSString *)title {
NIMMessage * revokeMessage = [[NIMMessage alloc] init];
[revokeMessage setValue:self.session forKey:@"session"];
[revokeMessage setValue:@(NIMMessageTypeTip) forKey:@"messageType"];
revokeMessage.timestamp = [PLTimeUtil getNowTimeTimestampMillisecond].longLongValue;
revokeMessage.text = title;
[[NIMSDK sharedSDK].conversationManager saveMessage:revokeMessage forSession:self.session completion:nil];
}
#pragma mark - Private Method
- (void)initInputView {
// 初始化输入工具条frame可以先这样临时设置下面的addBottomInputBarView方法会重置输入条frame
// 如果你想要自定义输入条View请参考TextFieldViewController代码
QInputBarViewConfiguration *inputBarViewConfiguration = [QInputBarViewConfiguration defaultInputBarViewConfiguration];
inputBarViewConfiguration.voiceButtonHidden = NO;//隐藏语音按钮
inputBarViewConfiguration.extendButtonHidden = YES;//隐藏拓展按钮
inputBarViewConfiguration.toolHidden = NO;
inputBarViewConfiguration.giftButtonHidden = NO;
inputBarViewConfiguration.cameraButtonHidden = NO;
inputBarViewConfiguration.photoButtonHidden = NO;
_inputBarView = [[QInputBarView alloc] initWithFrame:CGRectMake(0,0,self.view.frame.size.width,inputBarViewConfiguration.inputViewHeight)];
[_inputBarView setupWithConfiguration:inputBarViewConfiguration];
_inputBarView.delegate = self;
//keyboard管理类用来管理键盘各大面板的切换
_keyboardManager = [[QKeyboardManager alloc] initWithViewController:self];
_keyboardManager.dataSource = self;
//因为addBottomInputBarView方法会立刻触发delegate所以这里需要先设置delegate
_keyboardManager.delegate = self;
[_keyboardManager addBottomInputBarView:_inputBarView belowViewController:NO];
//把输入框(如果有的话)绑定给管理类
[_keyboardManager bindTextView:_inputBarView.inputTextView];
}
- (void)initViews {
self.sessionNavView.isInRoom = self.openType == SessionListOpenTypeRoom;
[self.view addSubview:self.sessionNavView];
[self.view addSubview:self.sessionTableView];
[self initInputView];
}
- (void)initLayout {
[self.sessionNavView mas_makeConstraints:^(MASConstraintMaker *make) {
make.height.mas_equalTo(self.openType == SessionListOpenTypeRoom ? 44 : kNavigationHeight);
make.left.top.right.mas_equalTo(self.view);
}];
}
- (void)viewDidLayoutSubviews{
if (self.openType == SessionListOpenTypeRoom) {
self.view.frame = CGRectMake(0, 0, KScreenWidth, kHalfScreenHeight);
}
}
- (void)initData {
NIMUser * user = [[NIMSDK sharedSDK].userManager userInfo:self.session.sessionId];
if (user) {
self.sessionNavView.title = user.userInfo.nickName;
} else {
self.sessionNavView.title = YMLocalizedString(@"XNDJTDDLoadingTool0");
}
[[NIMSDK sharedSDK].conversationManager markAllMessagesReadInSession:self.session];
[self.presenter getChatLimitReceiverUid:self.session.sessionId];
[self.presenter getUserInfo:self.session.sessionId];
}
- (BOOL)isExistMessages:(NIMMessage *)message{
BOOL isExist = NO;
NIMMessage * model;
for (NIMMessage *item in self.messages.reverseObjectEnumerator.allObjects) {
if ([item isKindOfClass:[NIMMessage class]] && [item.messageId isEqualToString:message.messageId]) {
model = item;
isExist = YES;
break;
}
}
if (model) {
model = message;
}
return isExist;
}
- (BOOL)showChatRiskView:(UserInfoModel *)userInfo {
if (userInfo.banAccount) {
return YES;
}
NSString * cacheUid = [[SessionRiskCache shareCache] getCloseChatRiskAlert:self.session.sessionId];
if (cacheUid && [cacheUid isEqualToString:self.session.sessionId]) {
return NO;
}
if ([[NIMSDK sharedSDK].userManager isMyFriend:self.session.sessionId]) {
return NO;
}
return YES;
}
#pragma mark - MessageProtocol
- (void)onGetLimitChat:(ChatLimitModel *)chatLimit {
BOOL chatDisabled = !chatLimit.chat && self.messages.count <= 0;
if (chatDisabled) {
SessionChatLimitView *chatLimitView = [[SessionChatLimitView alloc] initWithChatLimit:chatLimit];
self.sessionTableView.tableHeaderView = chatLimitView;
} else {
self.sessionTableView.tableHeaderView = nil;
}
self.inputBarView.userInteractionEnabled = !chatDisabled;
if (chatDisabled) {
self.inputBarView.inputTextView.placeholder = YMLocalizedString(@"SessionViewController1");
} else {
self.inputBarView.inputTextView.placeholder = YMLocalizedString(@"SessionViewController2");
}
}
///获取用户信息成功
- (void)onGetSessionUserInfoSuccess:(UserInfoModel *)userInfo {
_userInfo = userInfo;
self.sessionNavView.userInfo = userInfo;
if (userInfo.roomUid && self.openType == SessionListOpenTypeDefault) {
if ([self showChatRiskView:userInfo]) {
self.riskAlertView.warning = userInfo.banAccount ? YMLocalizedString(@"SessionViewController17") : YMLocalizedString(@"SessionViewController18");
if (!self.riskAlertView.superview) {
[self.view addSubview:self.riskAlertView];
[self.riskAlertView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.mas_equalTo(self.view);
make.top.mas_equalTo(self.sessionNavView.mas_bottom);
make.height.mas_equalTo(20);
}];
}
[self.sessionTableView mas_updateConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(self.sessionNavView.mas_bottom).mas_offset(20);
}];
} else {
[self.sessionTableView mas_updateConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(self.sessionNavView.mas_bottom).mas_offset(0);
}];
}
} else {
if ([self showChatRiskView:userInfo]) {
self.riskAlertView.warning = userInfo.banAccount ? YMLocalizedString(@"SessionViewController17") : YMLocalizedString(@"SessionViewController18");
if (!self.riskAlertView.superview) {
[self.view addSubview:self.riskAlertView];
[self.riskAlertView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.mas_equalTo(self.view);
make.top.mas_equalTo(self.sessionNavView.mas_bottom);
make.height.mas_equalTo(20);
}];
}
[self.sessionTableView mas_updateConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(self.sessionNavView.mas_bottom).mas_offset(20);
}];
} else {
[self.sessionTableView mas_updateConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(self.sessionNavView.mas_bottom).mas_offset(0);
}];
}
}
}
- (void)getFansLikeSuccess:(BOOL)isLike {
self.sessionNavView.isLike = isLike;
if(self.isAttention == YES && isLike == NO){
[self startAttention];
}
}
- (void)attentionUserSuccess:(NSString *)uid {
if ([uid isEqualToString:self.session.sessionId]) {
[self showSuccessToast:YMLocalizedString(@"SessionViewController7")];
self.sessionNavView.isLike = YES;
}
}
- (void)onGetUserInfoSuccess:(UserInfoModel *)userInfo {
self.userInfo = userInfo;
[self.sessionTableView reloadData];
}
#pragma mark - MessageCellDelegate
- (void)updateMessageSuccess:(NIMMessage *)message {
if ([message.session.sessionId isEqualToString:self.session.sessionId]) {
[self.sessionTableView reloadData];
}
}
- (void)didTapAvatar:(NSString *)uid {
if (uid.length > 0 && ![NIMMessageUtils isOfficalAccount:uid]) {
if ([ClientConfig shareConfig].canOpen) {
XPMineUserInfoViewController * infoVC = [[XPMineUserInfoViewController alloc] init];
infoVC.uid = uid.integerValue;
[[self getKeyWindowNav] pushViewController:infoVC animated:YES];
}else{
XPMineSimpleUserInfoViewController * infoVC = [[XPMineSimpleUserInfoViewController alloc] init];
infoVC.uid = uid.integerValue;
[[self getKeyWindowNav] pushViewController:infoVC animated:YES];
}
}
}
- (void)deleteMessageSuccess:(NIMMessage *)message {
MessageBaseModel * revokeMessage;
for (int i = 0; i < self.messages.count; i++) {
MessageBaseModel * message1 = [self.messages safeObjectAtIndex1:i];
if ([message.messageId isEqualToString: message1.message.messageId]) {
revokeMessage = message1;
break;
}
}
if (revokeMessage) {
[self.messages removeObject:revokeMessage];
[self.sessionTableView reloadData];
}
}
- (void)revokeMessageSuccess:(NIMMessage *)message {
MessageBaseModel * revokeMessage;
for (int i = 0; i < self.messages.count; i++) {
MessageBaseModel * message1 = [self.messages safeObjectAtIndex1:i];
if ([message.messageId isEqualToString:message1.message.messageId]) {
revokeMessage = message1;
break;
}
}
if (revokeMessage) {
[self.messages removeObject:revokeMessage];
// 插入一条撤回消息
[self addRevokeMessage:message title:YMLocalizedString(@"SessionViewController8")];
}
}
-(void)startAttention{
[self.presenter attentionUser:self.session.sessionId];
}
#pragma mark - SessionNavViewDelegate
- (void)sessionNavView:(SessionNavView *)view didClickLike:(UIButton *)sender {
[StatisticsServiceHelper trackEventWithKey:StatisticsServiceEvent_chat_toolbar_fans_click];
[self.presenter attentionUser:self.session.sessionId];
}
- (void)sessionNavView:(SessionNavView *)view didClickBack:(UIButton *)sender {
if (self.openType == SessionListOpenTypeRoom) {
CATransition *transition = [CATransition animation];
transition.duration = 0.3f;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionPush;
transition.subtype = kCATransitionFromLeft;
[self.view.superview.layer addAnimation:transition forKey:nil];
[self willMoveToParentViewController:nil]; //1
[self.view removeFromSuperview]; //2
[self removeFromParentViewController]; //3
return;
}
[self.navigationController popViewControllerAnimated:YES];
}
- (void)sessionNavView:(SessionNavView *)view didClickReport:(UIButton *)sender {
[StatisticsServiceHelper trackEventWithKey:StatisticsServiceEvent_chat_toolbar_set_click];
SessionInfoViewController * reportVC = [[SessionInfoViewController alloc] init];
reportVC.session = self.session;
reportVC.stickTopMessages = self.stickTopMessages;
reportVC.userInfo = self.userInfo;
[self.getKeyWindowNav pushViewController:reportVC animated:YES];
}
- (void)sessionNavView:(SessionNavView *)view didRoomLive:(NSString *)roomUid {
[StatisticsServiceHelper trackEventWithKey:StatisticsServiceEvent_chat_dialogue_revocation_click];
if (self.openType == SessionListOpenTypeDefault) {
__block BOOL isSameRoom = NO;
__block RoomInfoModel *roomModel;
[self.getKeyWindowNav.viewControllers enumerateObjectsUsingBlock:^(__kindof UIViewController * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
if ([obj isKindOfClass:[XPRoomViewController class]]) {
XPRoomViewController<RoomHostDelegate> * rooomVC = obj;
[[self getKeyWindowNav] popToRootViewControllerAnimated:NO];
roomModel = rooomVC.getRoomInfo;
if(rooomVC.getRoomInfo.uid == [roomUid integerValue]) {
isSameRoom = YES;
} else {
[rooomVC exitRoom];
}
*stop = YES;
}
}];
if (!isSameRoom) {
if (roomModel.type == RoomType_MiniGame) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[XPRoomViewController openRoom:roomUid fromNick:self.userInfo.nick fromType:UserEnterRoomFromType_Follow_User fromUid:[NSString stringWithFormat:@"%ld", self.userInfo.uid] viewController:[[XCCurrentVCStackManager shareManager] getCurrentVC]];
});
} else {
[XPRoomViewController openRoom:roomUid fromNick:self.userInfo.nick fromType:UserEnterRoomFromType_Follow_User fromUid:[NSString stringWithFormat:@"%ld", self.userInfo.uid] viewController:self];
}
}
}
}
#pragma mark - UITableViewDataSource
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 2;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (section == 0) {
if ([NIMMessageUtils isOfficalAccount:self.session.sessionId]) {
return 0;
}
return self.userInfo ? 1 : 0;
} else {
return self.messages.count;
}
}
- (nonnull UITableViewCell *)tableView:(nonnull UITableView *)tableView cellForRowAtIndexPath:(nonnull NSIndexPath *)indexPath {
if (indexPath.section == 0) {
SessionUserInfoTableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([SessionUserInfoTableViewCell class])];
if (cell == nil) {
///如果没有的话 根据identifier 注册一下 重新获取一下即可
[tableView registerClass:[SessionUserInfoTableViewCell class] forCellReuseIdentifier:NSStringFromClass([SessionUserInfoTableViewCell class])];
cell = [[SessionUserInfoTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:NSStringFromClass([SessionUserInfoTableViewCell class])];
}
cell.userInfo = self.userInfo;
cell.delegate = self;
return cell;
} else {
MessageBaseModel * message = [self.messages safeObjectAtIndex1:indexPath.row];
NSString * identifier = [message cellContent:message];
///从复用池中获取所需要的cell
MessageCell * cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (!cell) {
///如果没有的话 根据identifier 注册一下 重新获取一下即可
[tableView registerClass:[MessageCell class] forCellReuseIdentifier:identifier];
///如果注册过了 就不需要判断cell是否为空
cell = [tableView dequeueReusableCellWithIdentifier:identifier];
}
cell.delegate = self;
[cell renderWithMessage:[self.messages safeObjectAtIndex1:indexPath.row]];
return cell;
}
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == 0) {
return self.userInfo.privatePhoto.count > 0 ? 182 : 100;
}
MessageBaseModel *msg = [self.messages safeObjectAtIndex1:indexPath.row];
return msg.height;
}
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
[self.keyboardManager hideAllBoardView];
}
#pragma mark - NIMChatManagerDelegate
- (void)onRecvMessages:(NSArray<NIMMessage *> *)messages {
NIMMessage *message = messages.firstObject;
NIMSession *session = message.session;
if (![session isEqual:self.session] || !messages.count) {
return;
}
for (NIMMessage *message in messages) {
[self addTimeMessage:message];
if (message.isDeleted) {
continue;
}
MessageBaseModel * model = [self modeTransformMessage:message];
[self.messages addObject:model];
}
[self.sessionTableView reloadData];
[self.sessionTableView nim_scrollToBottom:YES];
[[NIMSDK sharedSDK].conversationManager markAllMessagesReadInSession:self.session];
}
- (void)sendMessage:(NIMMessage *)message didCompleteWithError:(NSError *)error {
if (message.session.sessionType != NIMSessionTypeP2P) {
return;
}
[self addTimeMessage:message];
if (![self isExistMessages:message]) {
MessageBaseModel * model = [self modeTransformMessage:message];
[self.messages addObject:model];
}
if (message.yidunAntiSpamRes) {
NSDictionary * spamRes = message.yidunAntiSpamRes.toJSONObject;
NSDictionary * spamResExt = ((NSString *)spamRes[@"ext"]).toJSONObject;
if ([spamResExt[@"antispam"][@"suggestion"] intValue] == 2) {
NSDictionary * dic = @{@"suggestion": @"2"};
message.localExt = dic;
[[NIMSDK sharedSDK].conversationManager updateMessage:message forSession:self.session completion:nil];
}
}
[self.sessionTableView reloadData];
[self.sessionTableView nim_scrollToBottom:YES];
}
/**
* 收到消息被撤回的通知
*
* @param notification 被撤回的消息信息
* @discusssion 云信在收到消息撤回后,会先从本地数据库中找到对应消息并进行删除,之后通知上层消息已删除
*/
- (void)onRecvRevokeMessageNotification:(NIMRevokeMessageNotification *)notification {
MessageBaseModel * revokeMessage;
for (int i = 0; i < self.messages.count; i++) {
MessageBaseModel * message1 = [self.messages safeObjectAtIndex1:i];
if ([notification.message.messageId isEqualToString:message1.message.messageId]) {
revokeMessage = message1;
break;
}
}
if (revokeMessage) {
[self.messages removeObject:revokeMessage];
[self.sessionTableView reloadData];
}
}
#pragma mark - NIMConversationManagerDelegate
- (void)messagesDeletedInSession:(NIMSession *)session {
[self.messages removeAllObjects];
[self initData];
}
- (void)didFailRetry:(NIMMessage *)message {
[Api getPrivateChatCheck:^(BaseModel * _Nullable data, NSInteger code, NSString * _Nullable msg) {
if(code == 200){
if (message.isReceivedMsg) {
[[NIMSDK sharedSDK].chatManager fetchMessageAttachment:message error:nil];
} else {
[[NIMSDK sharedSDK].chatManager resendMessage:message error:nil];
}
return;
}
[self showErrorToast:msg];
} content:@"" toUid:self.session.sessionId];
}
- (void)sendTextMessage:(NSString *)text {
[Api getPrivateChatCheck:^(BaseModel * _Nullable data, NSInteger code, NSString * _Nullable msg) {
if(code == 200){
NIMMessage *message = [NIMMessageMaker msgWithText:text];
message.apnsPayload = @{@"uid": [AccountInfoStorage instance].getUid //表明该条消息的发送者的账号或者消息所属的群组 ID
};
[[[NIMSDK sharedSDK] chatManager] sendMessage:message toSession:self.session error:nil];
return;
}
[self showErrorToast:msg];
} content:text toUid:self.session.sessionId];
}
- (void)audioRecordCompletion:(NSString *)recordPath {
[Api getPrivateChatCheck:^(BaseModel * _Nullable data, NSInteger code, NSString * _Nullable msg) {
if(code == 200){
NIMMessage *message = [NIMMessageMaker msgWithAudio:recordPath];
message.apnsPayload = @{@"uid": [AccountInfoStorage instance].getUid //表明该条消息的发送者的账号或者消息所属的群组 ID
};
[[[NIMSDK sharedSDK] chatManager] sendMessage:message toSession:self.session error:nil];
return;
}
[self showErrorToast:msg];
} content:@"" toUid:self.session.sessionId];
}
#pragma mark - TZImagePickerControllerDelegate
- (void)imagePickerController:(TZImagePickerController *)picker didFinishPickingPhotos:(NSArray<UIImage *> *)photos sourceAssets:(NSArray *)assets isSelectOriginalPhoto:(BOOL)isSelectOriginalPhoto infos:(NSArray<NSDictionary *> *)infos {
[photos enumerateObjectsUsingBlock:^(UIImage * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
if (obj) {
[Api getPrivateChatCheck:^(BaseModel * _Nullable data, NSInteger code, NSString * _Nullable msg) {
if(code == 200){
// 构造出具体会话
NIMMessage * message = [NIMMessageMaker msgWithImage:obj];
message.apnsPayload = @{@"uid": [AccountInfoStorage instance].getUid //表明该条消息的发送者的账号或者消息所属的群组 ID
};
// 发送消息
[[NIMSDK sharedSDK].chatManager sendMessage:message toSession:self.session error:nil];
return;
}
[self showErrorToast:msg];
} content:@"" toUid:self.session.sessionId];
}
}];
}
#pragma mark - SessionRiskViewDelegate
- (void)sessionRiskViewCloseButtonClick:(SessionRiskView *)view {
[[SessionRiskCache shareCache] saveCloseRisk:self.session.sessionId];
[self.riskAlertView removeFromSuperview];
[self.sessionTableView mas_updateConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(self.sessionNavView.mas_bottom).mas_offset(0);
}];
}
#pragma mark - SessionUserInfoTableViewCellDelegate
- (void)sessionUserInfoTableViewCell:(SessionUserInfoTableViewCell *)view showUserInfoVC:(UserInfoModel *)userInfo {
[self didTapAvatar:[NSString stringWithFormat:@"%ld", userInfo.uid]];
}
#pragma mark - InputBoardDataSource
//@return 点加号按钮弹出的拓展面板View且无需设置frame
- (UIView *)keyboardManagerExtendBoardView:(QKeyboardManager *)keyboardManager {
UIView *boardView = [UIView new];
boardView.backgroundColor = UIColor.clearColor;
return boardView;
}
//@return 点表情按钮弹出的表情面板View且无需设置frame
- (UIView *)keyboardManagerEmotionBoardView:(QKeyboardManager *)keyboardManager {
QEmotionBoardView *emotionView = [[QEmotionBoardView alloc] init];
QEmotionHelper *faceManager = [QEmotionHelper sharedEmotionHelper];
emotionView.emotions = faceManager.emotionArray;
emotionView.delegate = self;
if (@available(iOS 11.0, *)) {
NSBundle *bundle = [NSBundle bundleForClass:[self class]];
emotionView.backgroundColor = [UIColor colorNamed:@"q_input_extend_bg" inBundle:bundle compatibleWithTraitCollection:nil];
} else {
emotionView.backgroundColor = [UIColor colorWithRed:(246)/255.0f green:(246)/255.0f blue:(246)/255.0f alpha:1];
}
return emotionView;
}
//@return 点表情按钮弹出的表情面板View且无需设置frame
- (UIView *)keyboardManagerPhotoBoardView:(QKeyboardManager *)keyboardManager{
QinputPhotoView *emotionView = [[QinputPhotoView alloc] init];
self.photoView = emotionView;
emotionView.photoList = self.phototArray;
emotionView.delegate = self;
emotionView.backgroundColor = [UIColor colorWithRed:(246)/255.0f green:(246)/255.0f blue:(246)/255.0f alpha:1];
return emotionView;
}
//@return 点表情按钮弹出的表情面板View的高度
- (CGFloat)keyboardManagerEmotionBoardHeight:(QKeyboardManager *)keyboardManager {
return 294;
}
//@return 点加号按钮弹出的拓展面板View的高度
- (CGFloat)keyboardManagerExtendBoardHeight:(QKeyboardManager *)keyboardManager {
return 174;
}
- (CGFloat)keyboardManagerPhotoBoardHeight:(QKeyboardManager *)keyboardManager {
return 184 + kSafeAreaBottomHeight;
}
//点击表情按钮,切换到表情面板
- (void)inputBarView:(QInputBarView *)inputBarView onEmotionButtonClick:(UIButton *)emotionSwitchButton {
if (emotionSwitchButton.isSelected) {
[_keyboardManager switchToEmotionBoardKeyboard];
} else {
_inputBarView.inputTextView.text = @"";
[_inputBarView textViewBecomeFirstResponder];
}
}
- (void)inputBarView:(QInputBarView *)inputBarView onVoiceSwitchButtonClick:(UIButton *)voiceSwitchButton {
if (!voiceSwitchButton.isSelected) {
_inputBarView.inputTextView.text = @"";
[_inputBarView textViewBecomeFirstResponder];
} else {
[_keyboardManager hideAllBoardView];
}
}
- (void)inputBarView:(QInputBarView *)inputBarView onGiftButtonClick:(UIButton *)emotionSwitchButton {
[_keyboardManager hideAllBoardView];
XPSendGiftView * giftView = [[XPSendGiftView alloc] initWithType:SendGiftType_User uid:nil];
XPGiftUserInfoModel * userModel = [[XPGiftUserInfoModel alloc] init];
userModel.avatar = self.userInfo.avatar;
userModel.nick = self.userInfo.nick;
userModel.uid = self.session.sessionId.integerValue;
userModel.isSelect = YES;
[giftView configGiftUsers:@[userModel]];
[self presentViewController:giftView animated:YES completion:nil];
}
- (void)inputBarView:(QInputBarView *)inputBarView onCameraButtonClick:(UIButton *)emotionSwitchButton {
[_keyboardManager hideAllBoardView];
@kWeakify(self);
[YYUtility checkCameraAvailable:^{
@kStrongify(self);
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
imagePicker.delegate = self;
imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
imagePicker.allowsEditing = YES;
[self presentViewController:imagePicker animated:YES completion:NULL];
} denied:^{
@kStrongify(self);
[self showNotPhoto:YMLocalizedString(@"SessionViewController19") content:YMLocalizedString(@"SessionViewController10")];
} restriction:^{
@kStrongify(self);
[self showNotPhoto:YMLocalizedString(@"SessionViewController19") content:YMLocalizedString(@"SessionViewController12")];
}];
}
- (void)inputBarView:(QInputBarView *)inputBarView onPhototButtonClick:(UIButton *)emotionSwitchButton {
if (emotionSwitchButton.isSelected) {
@kWeakify(self);
[YYUtility checkAssetsLibrayAvailable:^{
@kStrongify(self);
[TZImagePickerConfig sharedInstance].allowPickingImage = YES;
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[[TZImageManager manager] getCameraRollAlbumWithFetchAssets:NO completion:^(TZAlbumModel *model) {
[[TZImageManager manager] getAssetsFromFetchResult:model.result completion:^(NSArray<TZAssetModel *> *models) {
dispatch_async(dispatch_get_main_queue(), ^{
NSMutableArray * array = [NSMutableArray array];
if (models.count > 40) {
for (int i = 0; i < 40; i++) {
TZAssetModel * assets = [models objectAtIndex:i];
QPhotoImageModel * infor = [[QPhotoImageModel alloc] init];
infor.isOrigin = NO;
infor.assetInfo = assets;
[array addObject:infor];
}
} else {
for (int i = 0; i < models.count; i++) {
TZAssetModel * assets = [models objectAtIndex:i];
QPhotoImageModel * infor = [[QPhotoImageModel alloc] init];
infor.isOrigin = NO;
infor.assetInfo = assets;
[array addObject:infor];
}
}
self.phototArray = array;
if (self.phototArray.count > 0) {
self.photoView.photoList = self.phototArray;
[self.keyboardManager switchToPhotoBoardKeyboard];
} else {
TZImagePickerController *imagePickerVc = [[TZImagePickerController alloc] initWithMaxImagesCount:1 delegate:self];
imagePickerVc.modalPresentationStyle = UIModalPresentationOverFullScreen;
imagePickerVc.allowPickingVideo = NO;
imagePickerVc.allowTakeVideo = NO;
imagePickerVc.naviBgColor = [DJDKMIMOMColor appCellBackgroundColor];
imagePickerVc.naviTitleColor = [DJDKMIMOMColor mainTextColor];
imagePickerVc.barItemTextColor = [DJDKMIMOMColor mainTextColor];
[self presentViewController:imagePickerVc animated:YES completion:nil];
}
});
}];
}];
});
} denied:^{
@kStrongify(self);
[self showNotPhoto:YMLocalizedString(@"SessionViewController20") content:YMLocalizedString(@"SessionViewController14")];
} restriction:^{
@kStrongify(self);
[self showNotPhoto:YMLocalizedString(@"SessionViewController20") content:YMLocalizedString(@"SessionViewController16")];
}];
} else {
[_keyboardManager hideAllBoardView];
_inputBarView.inputTextView.text = @"";
[_inputBarView textViewResignFirstResponder];
}
}
- (void)showNotPhoto:(NSString *)title content:(NSString *)content {
TTAlertConfig *config = [[TTAlertConfig alloc] init];
config.title = title;
config.message = content;
[TTPopup alertWithConfig:config confirmHandler:^{
NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
if ([[UIApplication sharedApplication] canOpenURL:url]) {
[[UIApplication sharedApplication] openURL:url options:@{} completionHandler:^(BOOL success) {
}];
}
} cancelHandler:^{
}];
}
#pragma mark - InputBoardDelegate
- (void)keyboardManager:(QKeyboardManager *)keyboardManager onWholeInputViewHeightDidChange:(CGFloat)wholeInputViewHeight reason:(WholeInputViewHeightDidChangeReason)reason {
[UIView animateWithDuration:0.2 animations:^{
[self.sessionTableView nim_scrollToBottom:NO];
[self.sessionTableView mas_remakeConstraints:^(MASConstraintMaker *make) {
make.left.right.mas_equalTo(self.view);
make.top.mas_equalTo(self.sessionNavView.mas_bottom);
make.bottom.mas_equalTo(self.view).offset(-wholeInputViewHeight - kSafeAreaBottomHeight);
}];
}];
}
#pragma mark - QEmotionBoardViewDelegate
/**
* 选中表情时的回调
* @param index 被选中的表情在`emotions`里的索引
* @param emotion 被选中的表情对应的`QMUIEmotion`对象
*/
- (void)emotionView:(QEmotionBoardView *)emotionView didSelectEmotion:(QEmotion *)emotion atIndex:(NSInteger)index {
//把😊插入到输入栏
[_inputBarView insertEmotion:emotion.displayName];
}
// 删除按钮的点击事件回调
- (void)emotionViewDidSelectDeleteButton:(QEmotionBoardView *)emotionView {
if (![_inputBarView deleteEmotion]){
//根据当前的光标,这次点击删除按钮并没有删除表情,那么就删除文字
[_inputBarView.inputTextView deleteBackward];
}
}
// 发送按钮的点击事件回调
- (void)emotionViewDidSelectSendButton:(QEmotionBoardView *)emotionView {
[self sendTextMessage:[_inputBarView textViewInputNormalText]];
_inputBarView.inputTextView.text = @"";
[_keyboardManager hideAllBoardView];
}
/**
* 点击了系统键盘的发送按钮
* @param inputNormalText "害~你好啊[微笑]"
*/
- (void)inputBarView:(QInputBarView *)inputBarView onKeyboardSendClick:(NSString *)inputNormalText {
[self sendTextMessage:inputNormalText];
_inputBarView.inputTextView.text = @"";
[_keyboardManager hideAllBoardView];
}
#pragma mark - QinputPhotoViewDelegate
- (void)qinputPhotoView:(QinputPhotoView *)view didClickSend:(NSArray *)photoList {
for (int i = 0; i < photoList.count; i++) {
QPhotoImageModel * imageInfo = [photoList safeObjectAtIndex1:i];
UIImage * image;
if (view.isOrigin) {
image = imageInfo.originImage;
} else {
image = imageInfo.compressImage;
}
if (image == nil){
continue;
}
// 发送消息
NIMMessage * message = [NIMMessageMaker msgWithImage:image];
[Api getPrivateChatCheck:^(BaseModel * _Nullable data, NSInteger code, NSString * _Nullable msg) {
if(code == 200){
message.apnsPayload = @{@"uid": [AccountInfoStorage instance].getUid //表明该条消息的发送者的账号或者消息所属的群组 ID
};
[[NIMSDK sharedSDK].chatManager sendMessage:message toSession:self.session error:nil];
[view resetChoosePhotos];
return;
}
[self showErrorToast:msg];
} content:@"" toUid:self.session.sessionId];
}
}
- (void)qinputPhotoView:(QinputPhotoView *)view didClickPhoto:(UIButton *)sender {
TZImagePickerController *imagePickerVc = [[TZImagePickerController alloc] initWithMaxImagesCount:1 delegate:self];
imagePickerVc.modalPresentationStyle = UIModalPresentationOverFullScreen;
imagePickerVc.allowPickingVideo = NO;
imagePickerVc.allowTakeVideo = NO;
imagePickerVc.naviBgColor = [DJDKMIMOMColor appCellBackgroundColor];
imagePickerVc.naviTitleColor = [DJDKMIMOMColor mainTextColor];
imagePickerVc.barItemTextColor = [DJDKMIMOMColor mainTextColor];
[self presentViewController:imagePickerVc animated:YES completion:nil];
}
#pragma mark - UIImagePickerControllerDelegate
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
UIImage *selectedPhoto = [info objectForKey:UIImagePickerControllerEditedImage];
if (selectedPhoto) {
if (picker.sourceType == UIImagePickerControllerSourceTypeCamera) {
UIImageWriteToSavedPhotosAlbum(selectedPhoto, nil, nil, nil);
}
[Api getPrivateChatCheck:^(BaseModel * _Nullable data, NSInteger code, NSString * _Nullable msg) {
if(code == 200){
// 构造出具体会话
NIMMessage * message = [NIMMessageMaker msgWithImage:selectedPhoto];
message.apnsPayload = @{@"uid": [AccountInfoStorage instance].getUid //表明该条消息的发送者的账号或者消息所属的群组 ID
};
// 发送消息
[[NIMSDK sharedSDK].chatManager sendMessage:message toSession:self.session error:nil];
return;
}
[self showErrorToast:msg];
} content:@"" toUid:self.session.sessionId];
}
[picker dismissViewControllerAnimated:YES completion:^{}];
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{
[picker dismissViewControllerAnimated:YES completion:^{
}];
}
#pragma mark - Getters And Setters
- (NSArray<MessageBaseModel *> *)messages {
if (!_messages) {
_messages = [[NSMutableArray alloc] init];
}
return _messages;
}
#pragma mark - Event Response
- (void)closeKeyBoard {
[self.view endEditing:YES];
[self.inputBarView textViewResignFirstResponder];
}
- (UITableView *)sessionTableView {
if (!_sessionTableView) {
_sessionTableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
_sessionTableView.delegate = self;
_sessionTableView.dataSource = self;
_sessionTableView.backgroundColor = UIColor.clearColor;
_sessionTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
_sessionTableView.showsVerticalScrollIndicator = NO;
if (@available(iOS 11.0, *)) {
_sessionTableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
}
// UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(closeKeyBoard)];
// [_sessionTableView addGestureRecognizer:tap];
}
return _sessionTableView;
}
- (SessionNavView *)sessionNavView {
if (!_sessionNavView) {
_sessionNavView = [[SessionNavView alloc] init];
_sessionNavView.delegate = self;
}
return _sessionNavView;
}
- (SessionRiskView *)riskAlertView {
if (!_riskAlertView) {
_riskAlertView = [[SessionRiskView alloc] init];
_riskAlertView.delegate = self;
}
return _riskAlertView;
}
@end