Files
yinmeng-ios/xplan-ios/Main/Room/View/MessageContainerView/XPRoomMessageContainerView.m
2021-10-27 19:07:10 +08:00

240 lines
7.7 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.

//
// XPRoomMessageView.m
// xplan-ios
//
// Created by 冯硕 on 2021/10/11.
//
#import "XPRoomMessageContainerView.h"
///Third
#import <Masonry/Masonry.h>
#import <NIMSDK/NIMSDK.h>
///Tool
#import "ThemeColor.h"
///Model
#import "XPRoomMessageDisplayModel.h"
///View
#import "XPRoomMessageTableViewCell.h"
#import "XPRoomMessageHeaderView.h"
#import "View/XPRoomMessageHeaderView.h"
///P
#import "XPIMRoomDelegate.h"
#import "XPIMManager.h"
@interface XPRoomMessageContainerView ()<UITableViewDelegate, UITableViewDataSource,XPIMRoomDelegate>
///列表
@property (nonatomic,strong) UITableView *messageTableView;
///数据源
@property (nonatomic,strong) NSMutableArray<XPRoomMessageDisplayModel *> *datasource;
///临时存放消息的数组
@property (nonatomic,strong) NSMutableArray<XPRoomMessageDisplayModel *> *tempArray;
///头部
@property (nonatomic,strong) XPRoomMessageHeaderView *headerView;
///底部有新的消息
@property (nonatomic,strong) UIButton *messageTipsBtn;
///是否处于正在爬楼
@property (nonatomic,assign) BOOL isPending;
@end
@implementation XPRoomMessageContainerView
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
[[XPIMManager shareManager].chatRoomManager addDelegate:self];
[self initSubViews];
[self initSubViewConstraints];
}
return self;
}
#pragma mark - Response
- (void)messagTipsBtnAction:(UIButton *)sender {
[self tryToappendAndScrollToBottom];
self.isPending = NO;
}
#pragma mark - Private Method
- (void)initSubViews {
[self addSubview:self.messageTableView];
[self addSubview:self.messageTipsBtn];
self.messageTableView.tableHeaderView = self.headerView;
}
- (void)initSubViewConstraints {
[self.messageTableView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(self).offset(15);
make.top.bottom.right.mas_equalTo(self);
}];
[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);
}];
}
#pragma mark - 添加数据并且做自动滚动
///添加信息
- (void)addRoomMessage:(NIMMessage *)message {
XPRoomMessageDisplayModel * model = [[XPRoomMessageDisplayModel alloc] initDisplayModel:message];
[self.tempArray addObject:model];
///开始加入数据
[self tryToappendAndScrollToBottom];
}
/// 添加数据并滚动到底部
- (void)tryToappendAndScrollToBottom {
// 处于爬楼状态更新更多按钮
[self updateMessageTipsBtnHidden];
if (!self.isPending) {
// 如果不处在爬楼状态,追加数据源并滚动到底部
[self appendAndScrollToBottom];
}
}
///更新底部有新的消息按钮的状态
- (void)updateMessageTipsBtnHidden {
if (self.isPending && self.tempArray.count > 0) {
self.messageTipsBtn.hidden = NO;
} else {
self.messageTipsBtn.hidden = YES;
}
}
///追加数据源
- (void)appendAndScrollToBottom {
if (self.tempArray.count < 1) {
return;
}
// 执行插入
NSMutableArray *indexPaths = [NSMutableArray array];
for (XPRoomMessageDisplayModel *item in self.tempArray) {
[self.datasource addObject:item];
[indexPaths addObject:[NSIndexPath indexPathForRow:self.datasource.count - 1 inSection:0]];
}
[self.messageTableView reloadData];
[self.tempArray removeAllObjects];
//执行插入动画并滚动
[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:UITableViewScrollPositionNone animated:animated]; //滚动到最后一行
}
#pragma mark - ScrollViewDelegate
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
// 手动拖拽开始
self.isPending = YES;
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
// 手动拖拽结束decelerate0松手时静止1松手时还在运动,会触发DidEndDecelerating方法
if (!decelerate) {
[self finishDraggingWith:scrollView];
}
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
// 静止后触发(手动)
[self finishDraggingWith:scrollView];
}
/** 手动拖拽动作彻底完成(减速到零) */
- (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;
// 如果不处在爬楼状态,追加数据源并滚动到底部
[self tryToappendAndScrollToBottom];
}
#pragma mark - UITableViewDelegate And UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.datasource.count;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
XPRoomMessageDisplayModel * model = [self.datasource objectAtIndex:indexPath.row];
return model.cellHeight;
}
- (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])];
}
XPRoomMessageDisplayModel * model = [self.datasource objectAtIndex:indexPath.row];
cell.displayModel = model;
return cell;
}
#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(messagTipsBtnAction:) forControlEvents:UIControlEventTouchUpInside];
_messageTipsBtn.hidden = YES;
}
return _messageTipsBtn;
}
- (NSMutableArray<XPRoomMessageDisplayModel *> *)datasource {
if (!_datasource) {
_datasource = [NSMutableArray array];
}
return _datasource;
}
- (NSMutableArray<XPRoomMessageDisplayModel *> *)tempArray {
if (!_tempArray) {
_tempArray = [NSMutableArray array];
}
return _tempArray;
}
@end