带多图选择的输入框控件
最近项目中需要用到类似贴吧的多图与文字输入回复和语音的输入,在网上看到了ZhipingYang的Demo,根据他的思路,做了一定的修改.简单实现了语音文字图片输入框的这个控件.
https://github.com/ZhipingYang/UUChatTableView
其中多图选择的框架是来自于ZL大大的杰作.
https://github.com/MakeZL/MLSelectPhoto
最终大致效果如下,界面还是太过粗糙.
代码如下.
//
// VTInputFunctionView.h
// TextField
//
// Created by 杨胜超 on 15/5/20.
// Copyright (c) 2015年 杨胜超. All rights reserved.
//
#import <UIKit/UIKit.h>
@class VTInputFunctionView;
@protocol VTInputFunctionViewDelegate <NSObject>
- (void)VTInputFunctionView:(VTInputFunctionView *)funcView sendMessage:(NSString *)message ImageArr:(NSArray *)imageArr;
- (void)VTinputFunctionView:(VTInputFunctionView *)funcView sendVoice:(NSData *)voice time:(NSInteger)second;
@end
@interface VTInputFunctionView : UIView<UIActionSheetDelegate,UIImagePickerControllerDelegate,UINavigationControllerDelegate>
@property (nonatomic,strong)UIButton *btnSendMessage;
@property (nonatomic,strong)UIButton *btnChangeVoiceState;
@property (nonatomic,strong)UIButton *btnVoiceRecord;
@property (nonatomic,strong)UITextView *TextViewInput;
@property (nonatomic,assign)BOOL isAbleToSendTextMessage;
@property (nonatomic,strong)UIViewController *superVC;
@property (nonatomic,assign)id<VTInputFunctionViewDelegate>v_delegate;
- (id)initWithSuperVC:(UIViewController *)superVC;
- (void)changeSendBtnWithPhoto:(BOOL)isPhoto;
@end
.m文件
//
// VTInputFunctionView.m
// TextField
//
// Created by 杨胜超 on 15/5/20.
// Copyright (c) 2015年 杨胜超. All rights reserved.
//
#import "VTInputFunctionView.h"
#import "Mp3Recorder.h"
#import "UUProgressHUD.h"
#import "ACMacros.h"
#import "MLSelectPhoto.h"
#import "MLSelectPhotoAssets.h"
#import "MLSelectPhotoPickerAssetsViewController.h"
#import "MLSelectPhotoBrowserViewController.h"
#define FRAME_HEIGHT 200
@interface VTInputFunctionView ()<UITextViewDelegate,Mp3RecorderDelegate>
{
BOOL isbeginVoiceRecord;
Mp3Recorder *MP3;
NSInteger playTime;
NSTimer *playTimer;
NSMutableArray *_imageArr;
UILabel *placeHold;
UIScrollView *imageScrollView;
UIButton *sendMessageAndImageBtn;
}
@end
@implementation VTInputFunctionView
- (id)initWithSuperVC:(UIViewController *)superVC
{
self.superVC = superVC;
CGRect frame = CGRectMake(0, Main_Screen_Height-40-64, Main_Screen_Width, 40);
self = [super initWithFrame:frame];
if (self)
{
MP3 = [[Mp3Recorder alloc]initWithDelegate:self];
_imageArr = [NSMutableArray arrayWithCapacity:0];
self.backgroundColor = [UIColor whiteColor];
/**
* 发送图文消息
*/
self.btnSendMessage = [UIButton buttonWithType:UIButtonTypeCustom];
self.btnSendMessage.frame = CGRectMake(Main_Screen_Width-40, 5, 30, 30);
self.isAbleToSendTextMessage = NO;
[self.btnSendMessage setTitle:@"" forState:UIControlStateNormal];
[self.btnSendMessage setBackgroundImage:[UIImage imageNamed:@"add"] forState:UIControlStateNormal];
self.btnSendMessage.titleLabel.font = [UIFont systemFontOfSize:12];
[self.btnSendMessage addTarget:self action:@selector(sendMessage:) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:self.btnSendMessage];
//改变状态(语音、文字)
self.btnChangeVoiceState = [UIButton buttonWithType:UIButtonTypeCustom];
self.btnChangeVoiceState.frame = CGRectMake(5, 5, 30, 30);
isbeginVoiceRecord = NO;
[self.btnChangeVoiceState setBackgroundImage:[UIImage imageNamed:@"chat_voice_record"] forState:UIControlStateNormal];
self.btnChangeVoiceState.titleLabel.font = [UIFont systemFontOfSize:12];
[self.btnChangeVoiceState addTarget:self action:@selector(voiceRecord:) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:self.btnChangeVoiceState];
//语音录入键
self.btnVoiceRecord = [UIButton buttonWithType:UIButtonTypeCustom];
self.btnVoiceRecord.frame = CGRectMake(70, 5, Main_Screen_Width-70*2, 30);
self.btnVoiceRecord.hidden = YES;
[self.btnVoiceRecord setBackgroundImage:[UIImage imageNamed:@"chat_message_back"] forState:UIControlStateNormal];
[self.btnVoiceRecord setTitleColor:[UIColor lightGrayColor] forState:UIControlStateNormal];
[self.btnVoiceRecord setTitleColor:[[UIColor lightGrayColor] colorWithAlphaComponent:0.5] forState:UIControlStateHighlighted];
[self.btnVoiceRecord setTitle:@"按住 说话" forState:UIControlStateNormal];
[self.btnVoiceRecord setTitle:@"松手 发送" forState:UIControlStateHighlighted];
//开始录音
[self.btnVoiceRecord addTarget:self action:@selector(beginRecordVoice:) forControlEvents:UIControlEventTouchDown];
//结束录音
[self.btnVoiceRecord addTarget:self action:@selector(endRecordVoice:) forControlEvents:UIControlEventTouchUpInside];
//取消录音
[self.btnVoiceRecord addTarget:self action:@selector(cancelRecordVoice:) forControlEvents:UIControlEventTouchUpOutside | UIControlEventTouchCancel];
//
[self.btnVoiceRecord addTarget:self action:@selector(RemindDragExit:) forControlEvents:UIControlEventTouchDragExit];
[self.btnVoiceRecord addTarget:self action:@selector(RemindDragEnter:) forControlEvents:UIControlEventTouchDragEnter];
[self addSubview:self.btnVoiceRecord];
//输入框
self.TextViewInput = [[UITextView alloc]initWithFrame:CGRectMake(45, 5, Main_Screen_Width-2*45, 30)];
self.TextViewInput.layer.cornerRadius = 4;
self.TextViewInput.layer.masksToBounds = YES;
self.TextViewInput.delegate = self;
self.TextViewInput.layer.borderWidth = 1;
self.TextViewInput.layer.borderColor = [[[UIColor lightGrayColor] colorWithAlphaComponent:0.4] CGColor];
[self addSubview:self.TextViewInput];
self.TextViewInput.returnKeyType = UIReturnKeyGo;
//输入框的提示语
placeHold = [[UILabel alloc]initWithFrame:CGRectMake(20, 0, 200, 30)];
placeHold.text = @"输入回复";
placeHold.textColor = [[UIColor lightGrayColor] colorWithAlphaComponent:0.8];
[self.TextViewInput addSubview:placeHold];
//分割线
self.layer.borderWidth = 1;
self.layer.borderColor = [[UIColor lightGrayColor] colorWithAlphaComponent:0.3].CGColor;
UIView *line = [[UIView alloc]initWithFrame:CGRectMake(0, 39.5, Main_Screen_Width, 0.5)];
line.backgroundColor = [UIColor lightGrayColor];
[self addSubview:line];
//多选的图片显示框
imageScrollView = [[UIScrollView alloc]initWithFrame:CGRectMake(0, 40+60, self.frame.size.width, 80)];
imageScrollView.showsHorizontalScrollIndicator = NO;
imageScrollView.showsVerticalScrollIndicator = NO;
[self addSubview:imageScrollView];
imageScrollView.scrollEnabled = YES;
imageScrollView.contentSize = CGSizeMake(10000, 100);
//发送按钮
sendMessageAndImageBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[sendMessageAndImageBtn setTitle:@"发送" forState:UIControlStateNormal];
sendMessageAndImageBtn.frame = CGRectMake(Main_Screen_Width-50, 50, 40, 40);
[sendMessageAndImageBtn setTitleColor:[UIColor orangeColor] forState:UIControlStateNormal];
//[self addSubview:sendMessageAndImageBtn];
[sendMessageAndImageBtn addTarget:self action:@selector(sendMessageAndImage:) forControlEvents:UIControlEventTouchUpInside];
//添加通知 结束编辑
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(textViewDidEndEditing:) name:UIKeyboardWillHideNotification object:nil];
// [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(keyboardChange:) name:UIKeyboardWillShowNotification object:nil];
// [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(keyboardChange:) name:UIKeyboardWillHideNotification object:nil];
// [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
// [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}
return self;
}
- (void)sendMessageAndImage:(UIButton *)button
{
if (self.TextViewInput.text.length == 0 && _imageArr.count == 0 )
{
NSLog(@"不能发送空内容");
}
else
{
[self.v_delegate VTInputFunctionView:self sendMessage:self.TextViewInput.text ImageArr:_imageArr];
}
}
#pragma mark - keyboard.notification
- (void)keyboardWillShow:(NSNotification *)note
{
CGRect keyboardF = [note.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGFloat duration = [note.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
[UIView animateWithDuration:duration animations:^{
if (_imageArr.count == 0)
{
self.frame = CGRectMake(0, Main_Screen_Height-40-64, Main_Screen_Width, 40);
}
else
{
self.frame = CGRectMake(0, Main_Screen_Height-40-64-150, Main_Screen_Width, 200);
}
self.frame = CGRectMake(0, Main_Screen_Height-40-64-keyboardF.size.height, Main_Screen_Width, keyboardF.size.height);
}];
}
- (void)keyboardWillHide:(NSNotification *)note
{
// 1.取出键盘弹出的时间
CGFloat duration = [note.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
// 2.执行动画
[UIView animateWithDuration:duration animations:^{
if (_imageArr.count == 0)
{
self.frame = CGRectMake(0, Main_Screen_Height-40-64, Main_Screen_Width, 40);
}
else
{
self.frame = CGRectMake(0, Main_Screen_Height-40-64-150, Main_Screen_Width, 200);
}
}];
}
/**
* 分开写 键盘打开---frame 高度变成40
//根据imageArr是否为空来判断高度为40还200
键盘关闭---frame 高度变成200
*
* @param notification
*/
-(void)keyboardChange:(NSNotification *)notification
{
NSDictionary *userInfo = [notification userInfo];
NSTimeInterval animationDuration;
UIViewAnimationCurve animationCurve;
CGRect keyboardEndFrame;
[[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&animationCurve];
[[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration];
[[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&keyboardEndFrame];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:animationDuration];
[UIView setAnimationCurve:animationCurve];
CGRect newFrame = self.frame;
CGFloat yy = 0.0f;
if (_imageArr.count == 0)
{
yy = 40;
}
else
{
yy = 200;
}
//newFrame.origin.y = keyboardEndFrame.origin.y-newFrame.size.height;
newFrame.origin.y = keyboardEndFrame.origin.y-yy;
self.frame = newFrame;
[UIView commitAnimations];
}
#pragma mark - 录音touch事件
- (void)beginRecordVoice:(UIButton *)button
{
[MP3 startRecord];
playTime = 0;
playTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(countVoiceTime) userInfo:nil repeats:YES];
[UUProgressHUD show];
}
- (void)endRecordVoice:(UIButton *)button
{
if (playTimer) {
[MP3 stopRecord];
[playTimer invalidate];
playTimer = nil;
}
}
- (void)cancelRecordVoice:(UIButton *)button
{
if (playTimer) {
[MP3 cancelRecord];
[playTimer invalidate];
playTimer = nil;
}
[UUProgressHUD dismissWithError:@"取消发送"];
}
- (void)RemindDragExit:(UIButton *)button
{
[UUProgressHUD changeSubTitle:@"松开手指 取消发送"];
}
- (void)RemindDragEnter:(UIButton *)button
{
[UUProgressHUD changeSubTitle:@"手指上滑 取消发送"];
}
/**
* 录音时间 如果超过60秒 直接结束
*/
- (void)countVoiceTime
{
playTime ++;
if (playTime>=60)
{
[self endRecordVoice:nil];
}
}
#pragma mark - Mp3RecorderDelegate
//回调录音资料
- (void)endConvertWithData:(NSData *)voiceData
{
[self.v_delegate VTinputFunctionView:self sendVoice:voiceData time:playTime+1];
[UUProgressHUD dismissWithSuccess:@"成功"];
//缓冲消失时间 (最好有block回调消失完成)
self.btnVoiceRecord.enabled = NO;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
self.btnVoiceRecord.enabled = YES;
});
}
/**
* 失败的情况---时间太短
*/
- (void)failRecord
{
[UUProgressHUD dismissWithSuccess:@"多说点儿"];
//缓冲消失时间 (最好有block回调消失完成)
self.btnVoiceRecord.enabled = NO;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
self.btnVoiceRecord.enabled = YES;
});
}
//改变输入与录音状态
/**
* 进入文本或者语音输入状态
*
* @param
*/
- (void)voiceRecord:(UIButton *)sender
{
self.btnVoiceRecord.hidden = !self.btnVoiceRecord.hidden;
self.TextViewInput.hidden = !self.TextViewInput.hidden;
isbeginVoiceRecord = !isbeginVoiceRecord;
if (isbeginVoiceRecord) {
[self.btnChangeVoiceState setBackgroundImage:[UIImage imageNamed:@"chat_ipunt_message"] forState:UIControlStateNormal];
[self.TextViewInput resignFirstResponder];
}else{
[self.btnChangeVoiceState setBackgroundImage:[UIImage imageNamed:@"chat_voice_record"] forState:UIControlStateNormal];
[self.TextViewInput becomeFirstResponder];
}
}
//发送消息(文字图片)
- (void)sendMessage:(UIButton *)sender
{
if (self.isAbleToSendTextMessage)
{
NSString *resultStr = [self.TextViewInput.text stringByReplacingOccurrencesOfString:@" " withString:@""];
[self.v_delegate VTInputFunctionView:self sendMessage:resultStr ImageArr:_imageArr];
}
else
{
[self.TextViewInput resignFirstResponder];
self.frame = CGRectMake(0, Main_Screen_Height-200-64, Main_Screen_Width, 200);
for (int i = 0; i<2; i++)
{
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.frame = CGRectMake(10+50*i, 50, 40, 40);
[btn addTarget:self action:@selector(selectImage:)
forControlEvents:UIControlEventTouchUpInside];
// [btn setTitle:@[@"拍摄",@"相册"][i] forState:UIControlStateNormal];
[btn setImage:[UIImage imageNamed:@[@"camera",@"keypicture"][i]] forState:UIControlStateNormal];
btn.tag = 1+i;
btn.layer.cornerRadius = 5;
btn.layer.masksToBounds = YES;
btn.backgroundColor = @[[UIColor colorWithRed:0/255.0 green:174/255.0 blue:239/255.0 alpha:1],[UIColor colorWithRed:246/255.0 green:139/255.0 blue:68/255.0 alpha:1]][i];
[self addSubview:btn];
}
}
}
#pragma mark - TextViewDelegate
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
if ([text isEqualToString:@"\n"])
{
[textView resignFirstResponder];
[self.v_delegate VTInputFunctionView:self sendMessage:textView.text ImageArr:_imageArr];
return NO;
}
return YES;
}
- (void)textViewDidBeginEditing:(UITextView *)textView
{
placeHold.hidden = self.TextViewInput.text.length > 0;
}
- (void)textViewDidChange:(UITextView *)textView
{
//开始编辑
//[self changeSendBtnWithPhoto:textView.text.length>0?NO:YES];
placeHold.hidden = textView.text.length>0;
}
- (void)changeSendBtnWithPhoto:(BOOL)isPhoto
{
self.isAbleToSendTextMessage = !isPhoto;
[self.btnSendMessage setTitle:isPhoto?@"":@"send" forState:UIControlStateNormal];
self.btnSendMessage.frame = RECT_CHANGE_width(self.btnSendMessage, isPhoto?30:35);
UIImage *image = [UIImage imageNamed:isPhoto?@"Chat_take_picture":@"chat_send_message"];
[self.btnSendMessage setBackgroundImage:image forState:UIControlStateNormal];
}
- (void)textViewDidEndEditing:(UITextView *)textView
{
placeHold.hidden = self.TextViewInput.text.length > 0;
}
- (void)selectImage:(UIButton *)btn
{
switch (btn.tag)
{
case 1:
{//相机
[self addCarema];
break;
}
case 2:
{//相册
[self openPicLibrary];
break;
}
default:
break;
}
}
-(void)openPicLibrary
{
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary])
{
MLSelectPhotoPickerViewController *pickerVc = [[MLSelectPhotoPickerViewController alloc] init];
pickerVc.minCount = 9;
pickerVc.status = PickerViewShowStatusCameraRoll;
[pickerVc show];
pickerVc.callBack = ^(NSArray *assets){
NSMutableArray *moImageArr = [NSMutableArray arrayWithCapacity:0];
for (int i = 0; i<assets.count; i++)
{
MLSelectPhotoAssets *asset = assets[i];
UIImage *image = [MLSelectPhotoPickerViewController getImageWithImageObj:asset];
[moImageArr addObject:image];
}
NSLog(@"选择了%lu张照片",(unsigned long)assets.count);
[_imageArr addObjectsFromArray:moImageArr];
NSLog(@"现在需要发送的照片共有%lu张",(unsigned long)_imageArr.count);
[self configScrollView];
};
}
}
-(void)addCarema
{//打开相机
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.allowsEditing = YES;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self.superVC presentViewController:picker animated:YES completion:^{}];
}else{
//如果没有提示用户
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:@"未找到摄像设备" delegate:nil cancelButtonTitle:@"好" otherButtonTitles:nil];
[alert show];
}
}
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
UIImage *editImage = [info objectForKey:UIImagePickerControllerEditedImage];
[self.superVC dismissViewControllerAnimated:YES completion:^{
//选中的照片保存到当前的view中
[_imageArr addObject:editImage];
[self configScrollView];
}];
}
- (void)configScrollView
{
for(UIImageView *image in imageScrollView.subviews)
{
[image removeFromSuperview];
}
CGFloat xx = 0.0f;
for (NSInteger i = 0; i<_imageArr.count; i++)
{
UIImageView *image = [[UIImageView alloc]initWithFrame:CGRectMake(10+80*i, 0, 70, 70)];
image.image = _imageArr[i];
[imageScrollView addSubview:image];
xx = CGRectGetMaxX(image.frame);
image.userInteractionEnabled = YES;
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.frame = CGRectMake(image.frame.size.width-20, 0, 20, 20);
btn.layer.cornerRadius = 10;
btn.layer.masksToBounds = YES;
//btn.backgroundColor = [UIColor redColor];
[btn setImage:[UIImage imageNamed:@"x_alt"] forState:UIControlStateNormal];
[image addSubview:btn];
btn.tag = 100 + i;
image.tag = 200 + i;
[btn addTarget:self action:@selector(deleteImage:) forControlEvents:UIControlEventTouchUpInside];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(lookImage:)];
[image addGestureRecognizer:tap];
}
imageScrollView.contentSize = CGSizeMake(xx +20, imageScrollView.frame.size.height);
}
#warning 查看图片实现相应的方法
- (void)lookImage:(UITapGestureRecognizer *)tap
{
UIImageView *image = (UIImageView *)tap.view;
// MLSelectPhotoBrowserViewController *browserVc = [[MLSelectPhotoBrowserViewController alloc] init];
// browserVc.currentPage = tap.view.tag-200;
// browserVc.photos = _imageArr;
// [self.superVC presentViewController:browserVc animated:YES completion:^{
//
// }];
}
- (void)deleteImage:(UIButton *)button
{
NSLog(@"%ld",(long)button.tag);
[_imageArr removeObjectAtIndex:button.tag-100];
[self configScrollView];
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{
[self.superVC dismissViewControllerAnimated:YES completion:nil];
}
-(void)dealloc
{
[[NSNotificationCenter defaultCenter]removeObserver:self];
}
@end