// // YOUPAIBBNIMSessionLayoutImpl.m // VQU // // Created by Elaine on 2021/10/26. // Copyright © 2021 MS. All rights reserved. // #import "YOUPAIBBNIMSessionLayoutImpl.h" #import "UITableView+NIMScrollToBottom.h" #import "NIMMessageCell.h" #import "NIMGlobalMacro.h" #import "NIMSessionTableAdapter.h" #import "UIView+NIM.h" #import "NIMKitKeyboardInfo.h" @interface YOUPAIBBNIMSessionLayoutImpl() { NSMutableArray *_youpaipinserts; CGFloat _youpaipinputViewHeight; } @property (nonatomic,strong) UIRefreshControl *refreshControl; @property (nonatomic,strong) NIMSession *session; @property (nonatomic,strong) id sessionConfig; @property (nonatomic,weak) id delegate; @end @implementation YOUPAIBBNIMSessionLayoutImpl - (instancetype)initWithSession:(NIMSession *)session config:(id)sessionConfig { self = [super init]; if (self) { _sessionConfig = sessionConfig; _session = session; _youpaipinserts = [[NSMutableArray alloc] init]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(youpaifmenuDidHide:) name:UIMenuControllerDidHideMenuNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(youpaifkeyboardWillChangeFrame:) name:NIMKitKeyboardWillChangeFrameNotification object:nil]; } return self; } - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; } - (void)reloadTable { [self.youpaiptableView reloadData]; } -(void)setYoupaiptableView:(UITableView *)youpaiptableView { BOOL change = _youpaiptableView != youpaiptableView; if (change) { _youpaiptableView = youpaiptableView; [self youpaifsetupRefreshControl]; } } - (void)resetLayout { [self youpaifadjustInputView]; [self youpaifadjustTableView]; } - (void)layoutAfterRefresh { [self.refreshControl endRefreshing]; [self.youpaiptableView reloadData]; } - (void)adjustOffset:(NSInteger)row { if (row >= 0) { dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:0]; [self.youpaiptableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES]; }); } } - (void)changeLayout:(CGFloat)youpaipinputViewHeight { BOOL change = _youpaipinputViewHeight != youpaipinputViewHeight; if (change) { _youpaipinputViewHeight = youpaipinputViewHeight; [self youpaifadjustInputView]; [self youpaifadjustTableView]; } } - (void)youpaifadjustInputView { UIView *superView = self.youpaipinputView.superview; UIEdgeInsets safeAreaInsets = UIEdgeInsetsZero; if (@available(iOS 11.0, *)) { safeAreaInsets = superView.safeAreaInsets; } self.youpaipinputView.nim_bottom = superView.nim_height - safeAreaInsets.bottom; } - (void)youpaifadjustTableView { //输入框是否弹起 BOOL youpaipinputViewUp = NO; switch (self.youpaipinputView.youpaipstatus) { case BBNIMInputStatusText: youpaipinputViewUp = [NIMKitKeyboardInfo instance].isVisiable; break; case BBNIMInputStatusAudio: youpaipinputViewUp = NO; break; case BBNIMInputStatusMore: case BBNIMInputStatusEmoticon: youpaipinputViewUp = YES; default: break; } self.youpaiptableView.userInteractionEnabled = !youpaipinputViewUp; CGRect rect = self.youpaiptableView.frame; //tableview 的位置 UIView *superView = self.youpaiptableView.superview; UIEdgeInsets safeAreaInsets = UIEdgeInsetsZero; if (@available(iOS 11.0, *)) { safeAreaInsets = superView.safeAreaInsets; } CGFloat containerSafeHeight = self.youpaiptableView.superview.frame.size.height - safeAreaInsets.bottom; rect.size.height = containerSafeHeight - self.youpaipinputView.youpaiptoolBar.nim_height; //tableview 的内容 inset UIEdgeInsets contentInsets = UIEdgeInsetsZero; CGFloat visiableHeight = 0; if (@available(iOS 11.0, *)) { contentInsets = self.youpaiptableView.adjustedContentInset; } else { contentInsets = self.youpaiptableView.contentInset; } [self.youpaiptableView reloadData]; //如果气泡过少,少于总高度,输入框视图需要顶到最后一个气泡的下面。 visiableHeight = visiableHeight + self.youpaiptableView.contentSize.height + contentInsets.top + contentInsets.bottom; visiableHeight = MIN(visiableHeight, rect.size.height); rect.origin.y = containerSafeHeight - visiableHeight - self.youpaipinputView.nim_height; rect.origin.y = rect.origin.y > 0? 0 : rect.origin.y; BOOL tableChanged = !CGRectEqualToRect(self.youpaiptableView.frame, rect); if (tableChanged) { [self.youpaiptableView setFrame:rect]; [self.youpaiptableView nim_scrollToBottom:YES]; } } #pragma mark - Notification - (void)youpaifmenuDidHide:(NSNotification *)notification { [UIMenuController sharedMenuController].menuItems = nil; } - (void)youpaifkeyboardWillChangeFrame:(NSNotification *)notification { if (!self.youpaiptableView.window) { //如果当前视图不是顶部视图,则不需要监听 return; } [self.youpaipinputView sizeToFit]; } #pragma mark - Private - (void)calculateContent:(NIMMessageModel *)model{ [model contentSize:self.youpaiptableView.nim_width]; } - (void)youpaifsetupRefreshControl { self.refreshControl = [[UIRefreshControl alloc] initWithFrame:CGRectMake(0, 0, 20, 20)]; if (@available(iOS 10.0, *)) { self.youpaiptableView.refreshControl = self.refreshControl; } else { [self.youpaiptableView addSubview: self.refreshControl]; } [self.refreshControl addTarget:self action:@selector(youpaifheaderRereshing:) forControlEvents:UIControlEventValueChanged]; } - (void)youpaifheaderRereshing:(id)sender { if ([self.delegate respondsToSelector:@selector(onRefresh)]) { [self.delegate onRefresh]; } } - (void)insert:(NSArray *)indexPaths animated:(BOOL)animated { if (!indexPaths.count) { return; } NSMutableArray *addIndexPathes = [NSMutableArray array]; [indexPaths enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { NSIndexPath *indexPath = [NSIndexPath indexPathForRow:[obj integerValue] inSection:0]; [addIndexPathes addObject:indexPath]; }]; [self.youpaiptableView beginUpdates]; [self.youpaiptableView insertRowsAtIndexPaths:addIndexPathes withRowAnimation:UITableViewRowAnimationBottom]; [self.youpaiptableView endUpdates]; [UIView animateWithDuration:0.25 delay:0 options:7 animations:^{ [self resetLayout]; } completion:nil]; [self.youpaiptableView nim_scrollToBottom:YES]; } - (void)remove:(NSArray *)indexPaths { [self.youpaiptableView beginUpdates]; [self.youpaiptableView deleteRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationNone]; [self.youpaiptableView endUpdates]; NSInteger row = [self.youpaiptableView numberOfRowsInSection:0] - 1; if (row > 0) { NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:0]; [self.youpaiptableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES]; } } - (void)update:(NSIndexPath *)indexPath { NIMMessageCell *cell = (NIMMessageCell *)[self.youpaiptableView cellForRowAtIndexPath:indexPath]; if (cell) { [self.youpaiptableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone]; CGFloat scrollOffsetY = self.youpaiptableView.contentOffset.y; [self.youpaiptableView setContentOffset:CGPointMake(self.youpaiptableView.contentOffset.x, scrollOffsetY) animated:NO]; } } - (BOOL)canInsertChatroomMessages { return !self.youpaiptableView.isDecelerating && !self.youpaiptableView.isDragging; } @end