Files
yinmeng-ios-store/yinmeng-ios/yinmeng-ios/Main/YinMeng/Message/View/Session/MewSessionToolbarView.m

484 lines
17 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.

//
// MessageToolbarView.m
// yinmeng-ios
//
// Created by 触海 on 2023/11/20.
//
#import "MewSessionToolbarView.h"
///Third
#import <Masonry/Masonry.h>
#import <NIMSDK/NIMSDK.h>
///Tool
#import "MEWThemeColor.h"
#import "YMMacro.h"
#import "NSArray+MewSafe.h"
///Model
#import "MewMessageMenuModel.h"
///View
#import "MewMessageToolMenuCollectionCell.h"
#import "MewSessionAudioRecordView.h"
#define TOOL_HEIGHT 60
#define MENU_HEIGHT 130
@interface MewSessionToolbarView ()<UICollectionViewDelegate, UICollectionViewDataSource, UITextFieldDelegate, NIMMediaManagerDelegate>
///最大的那个容器
@property (nonatomic,strong) UIStackView *stackView;
///上部分的功能的容器
@property (nonatomic,strong) UIStackView *toolStackView;
///切换语音和文字的按钮
@property (nonatomic,strong) UIButton *changeButton;
///更多按钮
@property (nonatomic,strong) UIButton *moreButton;
///语音和输入框的
@property (nonatomic,strong) UIStackView *audioStackView;
///输入框背景
@property (nonatomic,strong) UIView * inputBackView;
///输入框
@property (nonatomic,strong) UITextField *inputView;
///语音
@property (nonatomic,strong) UIButton *audioButton;
///列表
@property (nonatomic,strong) UICollectionView *collectionView;
///底部的view
@property (nonatomic,strong) UIView * placeView;
///菜单数据
@property (nonatomic,strong) NSArray<MewMessageMenuModel *> *menuList;
///录音的view
@property (nonatomic,strong) MewSessionAudioRecordView *audioRecordView;
@end
@implementation MewSessionToolbarView
- (void)dealloc {
[[NIMSDK sharedSDK].mediaManager removeDelegate:self];
}
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
[[NIMSDK sharedSDK].mediaManager addDelegate:self];
[self mew_addNotification];
[self mew_addAudioButtonAction];
[self initSubViews];
[self initSubViewConstraints];
}
return self;
}
#pragma mark - Public Method
- (void)mew_foldToolMenuView {
[self.inputView resignFirstResponder];
if (self.collectionView.hidden == NO) {
self.collectionView.hidden = YES;
self.moreButton.selected = NO;
}
}
#pragma mark - Private Method
- (void)mew_addAudioButtonAction {
///button 周围有一个70px的范围 超出这个范围的话 就是out 在这个范围的话就是in 从范围外到范围内的话就是enter 从范围内到范围外的话exit
[self.audioButton addTarget:self action:@selector(mew_audioTouchDownAction) forControlEvents:UIControlEventTouchDown];
[self.audioButton addTarget:self action:@selector(mew_audioTouchUpOutsideAction) forControlEvents:UIControlEventTouchUpOutside];
[self.audioButton addTarget:self action:@selector(mew_audioTouchUpInsideAction) forControlEvents:UIControlEventTouchUpInside];
[self.audioButton addTarget:self action:@selector(mew_audioTouchDragEnterAction) forControlEvents:UIControlEventTouchDragEnter];
[self.audioButton addTarget:self action:@selector(mew_audioTouchDragExitAction) forControlEvents:UIControlEventTouchDragExit];
}
- (void)mew_addNotification {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mew_keyboardWillHidden:) name:UIKeyboardWillHideNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mew_keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
}
- (void)initSubViews {
self.backgroundColor = [MEWThemeColor mewAppCellBackgroundColor];
[self addSubview:self.stackView];
[self.stackView addArrangedSubview:self.toolStackView];
[self.stackView addArrangedSubview:self.collectionView];
[self.stackView addArrangedSubview:self.placeView];
[self.toolStackView addArrangedSubview:self.changeButton];
[self.toolStackView addArrangedSubview:self.audioStackView];
[self.toolStackView addArrangedSubview:self.moreButton];
[self.audioStackView addArrangedSubview:self.inputBackView];
[self.audioStackView addArrangedSubview:self.audioButton];
[self.inputBackView addSubview:self.inputView];
}
- (void)initSubViewConstraints {
[self mas_makeConstraints:^(MASConstraintMaker *make) {
make.bottom.mas_equalTo(self.stackView);
}];
[self.stackView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.mas_equalTo(self).inset(15);
make.top.mas_equalTo(self);
}];
[self.toolStackView mas_makeConstraints:^(MASConstraintMaker *make) {
make.height.mas_equalTo(TOOL_HEIGHT);
}];
[self.collectionView mas_makeConstraints:^(MASConstraintMaker *make) {
make.height.mas_equalTo(MENU_HEIGHT);
}];
[self.placeView mas_makeConstraints:^(MASConstraintMaker *make) {
make.height.mas_equalTo(kSafeAreaBottomHeight);
}];
[self.changeButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.size.mas_equalTo(CGSizeMake(40, 40));
}];
[self.moreButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.size.mas_equalTo(CGSizeMake(40, 40));
}];
[self.audioStackView mas_makeConstraints:^(MASConstraintMaker *make) {
make.height.mas_equalTo(40);
}];
[self.inputView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(self.inputBackView.mas_left).offset(16);
make.top.bottom.mas_equalTo(self.inputBackView);
make.right.mas_equalTo(self.inputBackView).offset(-5);
}];
}
#pragma mark - UICollectionViewDelegate And UICollectionViewDatasource
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return self.menuList.count;
}
- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
MewMessageToolMenuCollectionCell * cell = [collectionView dequeueReusableCellWithReuseIdentifier:NSStringFromClass([MewMessageToolMenuCollectionCell class]) forIndexPath:indexPath];
MewMessageMenuModel * model = [self.menuList mewSafeObjectAtIndex:indexPath.row];
cell.imageName = model.imageName;
return cell;
}
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
[collectionView deselectItemAtIndexPath:indexPath animated:YES];
if (self.menuList.count > 0) {
MewMessageMenuModel * model = [self.menuList mewSafeObjectAtIndex:indexPath.row];
if (self.delegate && [self.delegate respondsToSelector:@selector(mew_didSelectMenuItem:)]) {
[self.delegate mew_didSelectMenuItem:model];
}
}
}
#pragma mark - UITextFieldDelegate
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
if (textField.text.length >0) {
if (self.delegate && [self.delegate respondsToSelector:@selector(mew_sendTextMessage:)]) {
[self.delegate mew_sendTextMessage:textField.text];
textField.text = nil;
}
}
return YES;
}
#pragma mark - NIMMediaManagerDelegate
/**
* 开始录制音频的回调
*
* @param filePath 录制的音频的文件路径
* @param error 错误信息
* @discussion 如果录音失败filePath 有可能为 nil
*/
- (void)recordAudio:(nullable NSString *)filePath didBeganWithError:(nullable NSError *)error {
NSLog(@"开始录制语音");
}
/**
* 录制音频完成后的回调
*
* @param filePath 录制完成的音频文件路径
* @param error 错误信息
*/
- (void)recordAudio:(nullable NSString *)filePath didCompletedWithError:(nullable NSError *)error {
if (filePath.length > 0 && error == nil) {
if (self.delegate && [self.delegate respondsToSelector:@selector(mew_audioRecordCompletion:)]) {
[self.delegate mew_audioRecordCompletion:filePath];
}
}
NSLog(@"录制音频完成后的回调 %@", filePath);
}
/**
* 录音被取消的回调
*/
- (void)recordAudioDidCancelled {
NSLog(@"录音被取消的回调");
}
/**
* 音频录制进度更新回调
*
* @param currentTime 当前录制的时间
*/
- (void)recordAudioProgress:(NSTimeInterval)currentTime {
[self.audioRecordView mew_updateAudioRecordProgress:currentTime];
}
/**
* 录音开始被打断回调
*/
- (void)recordAudioInterruptionBegin {
[self.audioRecordView mew_cancelAudioRecord];
}
#pragma mark - Event Response
- (void)mew_keyboardWillShow:(NSNotification *)notification {
if (self.collectionView.hidden == NO) {
self.collectionView.hidden = YES;
self.moreButton.selected = NO;
}
NSDictionary *userInfo = [notification userInfo];
CGRect keyboardEndFrame = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
if (CGRectIsNull(keyboardEndFrame)) {
return;
}
UIViewAnimationCurve animationCurve = [userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue];
NSInteger animationCurveOption = (animationCurve << 16);
double animationDuration = [userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
[UIView animateWithDuration:animationDuration delay:0.0 options:animationCurveOption animations:^{
if (self.delegate && [self.delegate respondsToSelector:@selector(mew_keyboardWillChangeFrame:)]) {
[self.delegate mew_keyboardWillChangeFrame:keyboardEndFrame];
}
} completion:^(BOOL finished) {
}];
}
- (void)mew_keyboardWillHidden:(NSNotification*)notification {
CGRect keyboardEndFrame = CGRectMake(0, 0, 0, 0);
[UIView animateWithDuration:0.25 animations:^{
if (self.delegate && [self.delegate respondsToSelector:@selector(mew_keyboardWillChangeFrame:)]) {
[self.delegate mew_keyboardWillChangeFrame:keyboardEndFrame];
}
}];
}
- (void)mew_changeButtonAction:(UIButton *)sender {
sender.selected = !sender.selected;
self.inputBackView.hidden = sender.selected;
self.audioButton.hidden = !sender.selected;
self.collectionView.hidden = YES;
self.moreButton.selected = NO;
if (sender.selected) {
[self.inputView resignFirstResponder];
} else {
[self.inputView becomeFirstResponder];
}
}
- (void)mew_moreButtonAction:(UIButton *)sender {
sender.selected = !sender.selected;
self.collectionView.hidden = !sender.selected;
[self.inputView resignFirstResponder];
CGRect keyboardEndFrame = CGRectMake(0, 0, 0, 0);
[UIView animateWithDuration:0.25 animations:^{
if (self.delegate && [self.delegate respondsToSelector:@selector(mew_keyboardWillChangeFrame:)]) {
[self.delegate mew_keyboardWillChangeFrame:keyboardEndFrame];
}
}];
}
- (void)mew_audioTouchDownAction {
self.audioButton.selected = YES;
///开始录音
if (!self.audioRecordView.superview) {
[[UIApplication sharedApplication].keyWindow addSubview:self.audioRecordView];
[self.audioRecordView mas_makeConstraints:^(MASConstraintMaker *make) {
make.center.mas_equalTo(self.audioRecordView.superview);
}];
[self.audioRecordView mew_configAudioRecord:@"mew_message_tool_audio_record_first" title:@"手指上滑,取消发送" isAnimation:YES];
[self.audioRecordView mew_beginAudioRecord];
}
}
- (void)mew_audioTouchUpOutsideAction {
self.audioButton.selected = NO;
///取消录音
[self.audioRecordView mew_cancelAudioRecord];
[self.audioRecordView removeFromSuperview];
}
- (void)mew_audioTouchUpInsideAction {
self.audioButton.selected = NO;
///手指抬起 完成录音
[self.audioRecordView mew_finishAudioRecord];
[self.audioRecordView removeFromSuperview];
}
- (void)mew_audioTouchDragEnterAction {
///手指上滑 取消发送
[self.audioRecordView mew_configAudioRecord:@"mew_message_tool_audio_record_first" title:@"手指上滑,取消发送" isAnimation:YES];
}
- (void)mew_audioTouchDragExitAction {
///松开手指 取消发送
[self.audioRecordView mew_configAudioRecord:@"mew_message_tool_audio_record_cancel" title:@"松开手指 取消发送" isAnimation:NO];
}
#pragma mark - Getters And Setters
- (void)setSendDisabled:(BOOL)sendDisabled {
self.userInteractionEnabled = !sendDisabled;
if (sendDisabled) {
self.inputView.text = @"";
NSAttributedString * attribute = [[NSAttributedString alloc] initWithString:_model == 2 ? @"互相关注成为好友可发起聊天" : @"暂时无法私聊" attributes:@{NSFontAttributeName : [UIFont systemFontOfSize:15], NSForegroundColorAttributeName : [MEWThemeColor mewSecondTextColor]}];
self.inputView.attributedPlaceholder = attribute;
} else {
NSAttributedString * attribute = [[NSAttributedString alloc] initWithString:@"请输入消息" attributes:@{NSFontAttributeName : [UIFont systemFontOfSize:15], NSForegroundColorAttributeName : [MEWThemeColor mewSecondTextColor]}];
self.inputView.attributedPlaceholder = attribute;
}
}
- (UIStackView *)stackView {
if (!_stackView) {
_stackView = [[UIStackView alloc] init];
_stackView.axis = UILayoutConstraintAxisVertical;
_stackView.distribution = UIStackViewDistributionFill;
_stackView.alignment = UIStackViewAlignmentFill;
_stackView.spacing = 0;
}
return _stackView;
}
- (UIStackView *)toolStackView {
if (!_toolStackView) {
_toolStackView = [[UIStackView alloc] init];
_toolStackView.axis = UILayoutConstraintAxisHorizontal;
_toolStackView.distribution = UIStackViewDistributionFill;
_toolStackView.alignment = UIStackViewAlignmentCenter;
_toolStackView.spacing = 8;
}
return _toolStackView;
}
- (UIButton *)changeButton {
if (!_changeButton) {
_changeButton = [UIButton buttonWithType:UIButtonTypeCustom];
[_changeButton setImage:[UIImage imageNamed:@"mew_message_session_tool_text"] forState:UIControlStateNormal];
[_changeButton setImage:[UIImage imageNamed:@"mew_message_session_tool_audio"] forState:UIControlStateSelected];
[_changeButton addTarget:self action:@selector(mew_changeButtonAction:) forControlEvents:UIControlEventTouchUpInside];
}
return _changeButton;
}
- (UIStackView *)audioStackView {
if (!_audioStackView) {
_audioStackView = [[UIStackView alloc] init];
_audioStackView.axis = UILayoutConstraintAxisHorizontal;
_audioStackView.distribution = UIStackViewDistributionFill;
_audioStackView.alignment = UIStackViewAlignmentFill;
_audioStackView.spacing = 0;
}
return _audioStackView;
}
- (UIView *)inputBackView {
if (!_inputBackView) {
_inputBackView = [[UIView alloc] init];
_inputBackView.backgroundColor = UIColorMewFromRGB(0xF1F1FA);
_inputBackView.layer.masksToBounds = YES;
_inputBackView.layer.cornerRadius = 4;
}
return _inputBackView;
}
- (UITextField *)inputView{
if (!_inputView) {
_inputView = [[UITextField alloc] init];
NSAttributedString * attribute = [[NSAttributedString alloc] initWithString:@"请输入消息" attributes:@{NSFontAttributeName : [UIFont systemFontOfSize:15], NSForegroundColorAttributeName : [MEWThemeColor mewSecondTextColor]}];
_inputView.attributedPlaceholder = attribute;
_inputView.borderStyle = UITextBorderStyleNone;
_inputView.tintColor = UIColorMewFromRGB(0xFFE710);
_inputView.textColor = [MEWThemeColor mewMainTextColor];
_inputView.font = [UIFont systemFontOfSize:12.f];
_inputView.delegate = self;
_inputView.autocorrectionType = UITextAutocorrectionTypeNo;
_inputView.returnKeyType = UIReturnKeySend;
}
return _inputView;
}
- (UIButton *)audioButton {
if (!_audioButton) {
_audioButton = [UIButton buttonWithType:UIButtonTypeCustom];
[_audioButton setTitle:@"按住说话" forState:UIControlStateNormal];
[_audioButton setTitle:@"松开结束" forState:UIControlStateSelected];
[_audioButton setTitleColor:[MEWThemeColor mewMainTextColor] forState:UIControlStateNormal];
_audioButton.titleLabel.font = [UIFont systemFontOfSize:14 weight:UIFontWeightMedium];
_audioButton.layer.masksToBounds = YES;
_audioButton.layer.cornerRadius = 4;
_audioButton.backgroundColor = UIColorMewFromRGB(0xF1F1FA);
_audioButton.hidden = YES;
}
return _audioButton;
}
- (UIButton *)moreButton {
if (!_moreButton) {
_moreButton = [UIButton buttonWithType:UIButtonTypeCustom];
[_moreButton setImage:[UIImage imageNamed:@"mew_message_session_tool_more_normal"] forState:UIControlStateNormal];
[_moreButton setImage:[UIImage imageNamed:@"message_session_tool_more_select"] forState:UIControlStateSelected];
[_moreButton addTarget:self action:@selector(mew_moreButtonAction:) forControlEvents:UIControlEventTouchUpInside];
}
return _moreButton;
}
- (UICollectionView *)collectionView{
if (!_collectionView) {
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
layout.sectionInset = UIEdgeInsetsMake(0, 0, 0, 0);
layout.itemSize = CGSizeMake(48, 48);
layout.minimumLineSpacing = 24;
layout.minimumInteritemSpacing = 10;
_collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout];
_collectionView.dataSource = self;
_collectionView.delegate = self;
_collectionView.backgroundColor = [UIColor clearColor];
_collectionView.hidden = YES;
[_collectionView registerClass:[MewMessageToolMenuCollectionCell class] forCellWithReuseIdentifier:NSStringFromClass([MewMessageToolMenuCollectionCell class])];
}
return _collectionView;
}
- (UIView *)placeView {
if (!_placeView) {
_placeView = [[UIView alloc] init];
_placeView.backgroundColor = [UIColor clearColor];
}
return _placeView;
}
- (NSArray<MewMessageMenuModel *> *)menuList {
if (!_menuList) {
MewMessageMenuModel * phototModel = [[MewMessageMenuModel alloc] init];
phototModel.imageName = @"mew_message_session_menu_photo";
phototModel.type= Mew_MessageMenuType_Photo;
_menuList = @[phototModel];
}
return _menuList;
}
- (MewSessionAudioRecordView *)audioRecordView {
if (!_audioRecordView) {
_audioRecordView = [[MewSessionAudioRecordView alloc] init];
}
return _audioRecordView;
}
@end