這幾天都不忙,就來寫寫博客了,繼上次
帶大家一步一步封裝聊天鍵盤(一)地址:http://www.cnblogs.com/bcblogs/p/4704046.html
帶大家一步一步封裝聊天鍵盤(二)地址:http://www.cnblogs.com/bcblogs/p/4707512.html
git也更新了,大家在拉一遍地址在第一篇里
今天我們來寫三,主要是把MoreView的里面的發送圖片啊,語音啊,視頻啊什么的都實現,今天主要實現的是發送圖片(因為這個最簡單...)
需求:點擊圖片按鈕,彈出actionsheet控件,選擇拍攝還是從圖片庫選擇
好吧,不啰嗦了,直接上代碼
- (void)didselectImageView:(NSInteger)index { switch (index) { case 0: [self createActionSheet]; break; default: break; } } - (void)createActionSheet { UIActionSheet *action=[[UIActionSheet alloc] initWithTitle:@"選取照片" delegate:self cancelButtonTitle:@"取消" destructiveButtonTitle:nil otherButtonTitles:@"從攝像頭選取", @"從圖片庫選擇",nil]; [action showInView:self]; } - (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex { switch (buttonIndex) { case 0: [self openCamera]; break; case 1: [self openLibary]; break; default: break; } } - (void)openCamera{ //打開系統相機 if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]){ UIImagePickerController *picker = [[UIImagePickerController alloc] init]; picker.delegate = self; picker.allowsEditing = YES; picker.sourceType = UIImagePickerControllerSourceTypeCamera; [self.currentCtr presentViewController:picker animated:YES completion:nil]; } } - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage]; if([self.delegate respondsToSelector:@selector(returnImage:)]){ [self.delegate returnImage:image]; } UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil); [self.currentCtr dismissViewControllerAnimated:YES completion:nil]; } - (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker { [self.currentCtr dismissViewControllerAnimated:YES completion:nil]; } - (void)openLibary{ if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]){ UIImagePickerController *picker = [[UIImagePickerController alloc] init]; picker.delegate = self; picker.allowsEditing = YES; picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary; [self.currentCtr presentViewController:picker animated:YES completion:nil]; } }
上次封裝的代理方法可以將點擊了第幾張圖片的事件傳回自定義的View,也就是BCKeyBoard,根據 - (void)didselectImageView:(NSInteger)index方法中的index來判斷點擊了第幾個圖片
這里我們用switch,因為它比較快,點擊了第一個圖片,就創建一個actionsheet,利用actionsheet的代理方法
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex來判斷點擊了第幾個按鈕
從而選擇打開相機還是打開相冊,在這里我發現個問題,因為在view里的對象是view,而不是viewcontroller所以不能使用presentViewController方法,雖然可以使用代理將點擊事件傳到控制器再在控制器去打開相機和相冊
但是,那不是我想要的,我想把所有的邏輯都封裝在自定義View里面,突然,靈光一閃,我把控制器當做一個屬性傳給自定義View,不就能調用外部控制器去使用presentViewController方法了(真是個天才,哈哈),還需要寫個代理方法
將拍攝的照片和從相冊里面選擇的照片傳回控制器,以便使用者使用
最后BCKeyBoard.h文件
#import <UIKit/UIKit.h> @protocol BCKeyBoardDelegate <NSObject> /** 發送的文字 */ - (void)didSendText:(NSString *)text; /** 回調返回高度 */ - (void)returnHeight:(CGFloat)height; /** 回調返回的圖片 */ - (void)returnImage:(UIImage *)image; @end @interface BCKeyBoard : UIView @property (nonatomic,weak)id <BCKeyBoardDelegate> delegate; @property (nonatomic,strong)NSArray *imageArray; /**< 點擊加號彈出的View中的圖片數組 */ @property (nonatomic,strong)NSString *placeholder; /**< 占位文字 */ @property (nonatomic,strong)UIColor *placeholderColor; /**< 占位文字顏色 */ @property (nonatomic,strong)UIViewController *currentCtr; @end
BCKeyBoard.m文件
#import "BCKeyBoard.h" #import "BCTextView.h" #import "DXFaceView.h" #import "BCMoreView.h" #define SCREEN_WIDTH ([[UIScreen mainScreen] bounds].size.width) #define SCREEN_HEIGHT ([[UIScreen mainScreen] bounds].size.height) #define kBCTextViewHeight 36 /**< 底部textView的高度 */ #define kHorizontalPadding 8 /**< 橫向間隔 */ #define kVerticalPadding 5 /**< 縱向間隔 */ @interface BCKeyBoard () <UITextViewDelegate,DXFaceDelegate,BCMoreViewDelegate,UIActionSheetDelegate,UINavigationControllerDelegate,UIImagePickerControllerDelegate> @property (nonatomic,strong)UIImageView *backgroundImageView; @property (nonatomic,strong)UIButton *faceBtn; @property (nonatomic,strong)UIButton *moreBtn; @property (nonatomic,strong)BCTextView *textView; @property (nonatomic,strong)UIView *faceView; @property (nonatomic,strong)UIView *moreView; @property (nonatomic,assign)CGFloat lastHeight; @property (nonatomic,strong)UIView *activeView; @end @implementation BCKeyBoard - (instancetype)initWithFrame:(CGRect)frame { if (frame.size.height < (kVerticalPadding * 2 + kBCTextViewHeight)) { frame.size.height = kVerticalPadding * 2 + kBCTextViewHeight; } self = [super initWithFrame:frame]; if (self) { [self createUI]; } return self; } - (void)setFrame:(CGRect)frame { if (frame.size.height < (kVerticalPadding * 2 + kBCTextViewHeight)) { frame.size.height = kVerticalPadding * 2 + kBCTextViewHeight; } [super setFrame:frame]; } - (void)createUI { _lastHeight = 30; //注冊鍵盤改變是調用 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChangeFrame:) name:UIKeyboardWillChangeFrameNotification object:nil]; self.backgroundImageView = [[UIImageView alloc] initWithFrame:self.bounds]; self.backgroundImageView.userInteractionEnabled = YES; self.backgroundImageView.image = [[UIImage imageNamed:@"messageToolbarBg"] stretchableImageWithLeftCapWidth:0.5 topCapHeight:10]; //表情按鈕 self.faceBtn = [UIButton buttonWithType:UIButtonTypeCustom]; self.faceBtn.frame = CGRectMake(kHorizontalPadding,kHorizontalPadding, 30, 30); [self.faceBtn addTarget:self action:@selector(willShowFaceView:) forControlEvents:UIControlEventTouchUpInside]; [self.faceBtn setBackgroundImage:[UIImage imageNamed:@"chatBar_face"] forState:UIControlStateNormal]; [self.faceBtn setBackgroundImage:[UIImage imageNamed:@"chatBar_keyboard"] forState:UIControlStateSelected]; [self addSubview:self.faceBtn]; //文本 self.textView = [[BCTextView alloc] initWithFrame:CGRectMake(CGRectGetMaxX(self.faceBtn.frame)+kHorizontalPadding, kHorizontalPadding, self.bounds.size.width - 4*kHorizontalPadding - 30*2, 30)]; self.textView.placeholderColor = self.placeholderColor; self.textView.returnKeyType = UIReturnKeySend; self.textView.scrollEnabled = NO; self.textView.backgroundColor = [UIColor clearColor]; self.textView.layer.borderColor = [UIColor colorWithWhite:0.8f alpha:1.0f].CGColor; self.textView.layer.borderWidth = 0.65f; self.textView.layer.cornerRadius = 6.0f; self.textView.delegate = self; //更多按鈕 self.moreBtn = [UIButton buttonWithType:UIButtonTypeCustom]; self.moreBtn.frame = CGRectMake(CGRectGetMaxX(self.textView.frame)+kHorizontalPadding,kHorizontalPadding,30,30); [self.moreBtn addTarget:self action:@selector(willShowactiveView:) forControlEvents:UIControlEventTouchUpInside]; [self.moreBtn setBackgroundImage:[UIImage imageNamed:@"chatBar_more"] forState:UIControlStateNormal]; [self.moreBtn setBackgroundImage:[UIImage imageNamed:@"chatBar_keyboard"] forState:UIControlStateSelected]; [self addSubview:self.backgroundImageView]; [self.backgroundImageView addSubview:self.textView]; [self.backgroundImageView addSubview:self.faceBtn]; [self.backgroundImageView addSubview:self.moreBtn]; if (!self.faceView) { self.faceView = [[DXFaceView alloc] initWithFrame:CGRectMake(0, (kHorizontalPadding * 2 + 30), self.frame.size.width, 200)]; [(DXFaceView *)self.faceView setDelegate:self]; self.faceView.backgroundColor = [UIColor whiteColor]; self.faceView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin; } if (!self.moreView) { self.moreView = [[BCMoreView alloc] initWithFrame:CGRectMake(0, (kHorizontalPadding * 2 + 30), self.frame.size.width, 200)]; self.moreView.backgroundColor = [UIColor whiteColor]; [(BCMoreView *)self.moreView setDelegate:self]; self.moreView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin; } } - (void)changeFrame:(CGFloat)height{ if (height == _lastHeight) { return; } else{ CGFloat changeHeight = height - _lastHeight; CGRect rect = self.frame; rect.size.height += changeHeight; rect.origin.y -= changeHeight; self.frame = rect; rect = self.backgroundImageView.frame; rect.size.height += changeHeight; self.backgroundImageView.frame = rect; [self.textView setContentOffset:CGPointMake(0.0f, (self.textView.contentSize.height - self.textView.frame.size.height) / 2) animated:YES]; CGRect frame = self.textView.frame; frame.size.height = height; self.textView.frame = frame; _lastHeight = height; if (self.delegate && [self.delegate respondsToSelector:@selector(returnHeight:)]) { [self.delegate returnHeight:height]; } } } - (void)setPlaceholder:(NSString *)placeholder { self.textView.placeholder = placeholder; } - (void)setPlaceholderColor:(UIColor *)placeholderColor { self.textView.placeholderColor = placeholderColor; } - (void)keyboardWillChangeFrame:(NSNotification *)notification{ NSDictionary *userInfo = notification.userInfo; CGRect endFrame = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue]; CGFloat duration = [userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue]; UIViewAnimationCurve curve = [userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue]; void(^animations)() = ^{ CGRect frame = self.frame; frame.origin.y = endFrame.origin.y - self.bounds.size.height; self.frame = frame; }; void(^completion)(BOOL) = ^(BOOL finished){ }; [UIView animateWithDuration:duration delay:0.0f options:(curve << 16 | UIViewAnimationOptionBeginFromCurrentState) animations:animations completion:completion]; } #pragma mark 表情View - (void)willShowFaceView:(UIButton *)btn { btn.selected = !btn.selected; if(btn.selected == YES){ [self willShowBottomView:self.faceView]; [self.textView resignFirstResponder]; }else{ [self willShowBottomView:nil]; [self.textView becomeFirstResponder]; } } #pragma mark 表更多View - (void)willShowactiveView:(UIButton *)btn { btn.selected = !btn.selected; if(btn.selected == YES){ [self willShowBottomView:self.moreView]; [self.textView resignFirstResponder]; [(BCMoreView *)self.moreView setImageArray:self.imageArray]; }else{ [self willShowBottomView:nil]; [self.textView becomeFirstResponder]; } } - (void)willShowBottomHeight:(CGFloat)bottomHeight { CGRect fromFrame = self.frame; CGFloat toHeight = self.backgroundImageView.frame.size.height + bottomHeight; CGRect toFrame = CGRectMake(fromFrame.origin.x, fromFrame.origin.y + (fromFrame.size.height - toHeight), fromFrame.size.width, toHeight); self.frame = toFrame; if (self.delegate && [self.delegate respondsToSelector:@selector(returnHeight:)]) { [self.delegate returnHeight:toHeight]; } } - (CGFloat)getTextViewContentH:(UITextView *)textView { return ceilf([textView sizeThatFits:textView.frame.size].height); } - (void)textViewDidBeginEditing:(UITextView *)textView { [self willShowBottomView:nil]; self.faceBtn.selected = NO; self.moreBtn.selected = NO; } - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text { if ([text isEqualToString:@"\n"]) { if ([self.delegate respondsToSelector:@selector(didSendText:)]) { [self.delegate didSendText:textView.text]; self.textView.text = @""; [self changeFrame:ceilf([textView sizeThatFits:textView.frame.size].height)]; } return NO; } return YES; } - (void)willShowBottomView:(UIView *)bottomView { if (![self.activeView isEqual:bottomView]) { CGFloat bottomHeight = bottomView ? bottomView.frame.size.height : 0; [self willShowBottomHeight:bottomHeight]; if (bottomView) { CGRect rect = bottomView.frame; rect.origin.y = CGRectGetMaxY(self.backgroundImageView.frame); bottomView.frame = rect; [self addSubview:bottomView]; } if (self.activeView) { [self.activeView removeFromSuperview]; } self.activeView = bottomView; } } - (void)textViewDidChange:(UITextView *)textView { [self changeFrame:ceilf([textView sizeThatFits:textView.frame.size].height)]; } - (void)selectedFacialView:(NSString *)str isDelete:(BOOL)isDelete { NSString *chatText = self.textView.text; if (!isDelete && str.length > 0) { self.textView.text = [NSString stringWithFormat:@"%@%@",chatText,str]; } else { if (chatText.length >= 2) { NSString *subStr = [chatText substringFromIndex:chatText.length-2]; if ([(DXFaceView *)self.faceView stringIsFace:subStr]) { self.textView.text = [chatText substringToIndex:chatText.length-2]; [self textViewDidChange:self.textView]; return; } } if (chatText.length > 0) { self.textView.text = [chatText substringToIndex:chatText.length-1]; } } [self textViewDidChange:self.textView]; } - (void)sendFace { NSString *chatText = self.textView.text; if (chatText.length > 0) { if ([self.delegate respondsToSelector:@selector(didSendText:)]) { [self.delegate didSendText:chatText]; self.textView.text = @""; [self changeFrame:ceilf([self.textView sizeThatFits:self.textView.frame.size].height)]; } } } - (void)didselectImageView:(NSInteger)index { switch (index) { case 0: [self createActionSheet]; break; default: break; } } - (void)createActionSheet { UIActionSheet *action=[[UIActionSheet alloc] initWithTitle:@"選取照片" delegate:self cancelButtonTitle:@"取消" destructiveButtonTitle:nil otherButtonTitles:@"從攝像頭選取", @"從圖片庫選擇",nil]; [action showInView:self]; } - (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex { switch (buttonIndex) { case 0: [self openCamera]; break; case 1: [self openLibary]; break; default: break; } } - (void)openCamera{ //打開系統相機 if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]){ UIImagePickerController *picker = [[UIImagePickerController alloc] init]; picker.delegate = self; picker.allowsEditing = YES; picker.sourceType = UIImagePickerControllerSourceTypeCamera; [self.currentCtr presentViewController:picker animated:YES completion:nil]; } } - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage]; if([self.delegate respondsToSelector:@selector(returnImage:)]){ [self.delegate returnImage:image]; } UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil); [self.currentCtr dismissViewControllerAnimated:YES completion:nil]; } - (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker { [self.currentCtr dismissViewControllerAnimated:YES completion:nil]; } - (void)openLibary{ if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]){ UIImagePickerController *picker = [[UIImagePickerController alloc] init]; picker.delegate = self; picker.allowsEditing = YES; picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary; [self.currentCtr presentViewController:picker animated:YES completion:nil]; } } - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillChangeFrameNotification object:nil]; } @end
viewController里面的使用方法
#import "ViewController.h" #import "BCKeyBoard.h" @interface ViewController () <BCKeyBoardDelegate> @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; NSArray *array = @[@"chatBar_colorMore_photoSelected",@"chatBar_colorMore_audioCall",@"chatBar_colorMore_location",@"chatBar_colorMore_video.png",@"chatBar_colorMore_video.png",@"chatBar_colorMore_video.png"]; BCKeyBoard *bc = [[BCKeyBoard alloc] initWithFrame:CGRectMake(0, [UIScreen mainScreen].bounds.size.height - 46, [UIScreen mainScreen].bounds.size.width,46)]; bc.delegate = self; bc.imageArray = array; bc.placeholder = @"我來說幾句"; bc.currentCtr = self; bc.placeholderColor = [UIColor colorWithRed:133/255 green:133/255 blue:133/255 alpha:0.5]; bc.backgroundColor = [UIColor clearColor]; [self.view addSubview:bc]; } - (void)didSendText:(NSString *)text { NSLog(@"%@",text); } - (void)returnHeight:(CGFloat)height { NSLog(@"%f",height); } - (void)returnImage:(UIImage *)image{ UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)]; imageView.image = image; [self.view addSubview:imageView]; } @end
運行效果
好啦,今天就到這里,大家看過了多評論啊,有什么問題和需要添加的功能也在評論里面寫哦,順便git上面點個star啊,謝謝啦。