带多图选择的输入框控件

带多图选择的输入框控件

最近项目中需要用到类似贴吧的多图与文字输入回复和语音的输入,在网上看到了ZhipingYang的Demo,根据他的思路,做了一定的修改.简单实现了语音文字图片输入框的这个控件.
https://github.com/ZhipingYang/UUChatTableView
其中多图选择的框架是来自于ZL大大的杰作.
https://github.com/MakeZL/MLSelectPhoto

最终大致效果如下,界面还是太过粗糙.
惦记第一个按钮和第二个按钮分别是照相与相册中选择

选完照片后以一个scrollview展示 红叉可动态删除

代码如下.


//
//  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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值