带大家一步一步封装一个聊天键盘(二)
2015-08-06 11:29
337 查看
继上次写了封装聊天键盘(一)地址(http://www.cnblogs.com/bcblogs/p/4704046.html),今天有时间就继续写吧,哈哈,有什么问题可以在评论里发给我哦(红色字体是我当时怎么想的)
上次写到表情键盘,今天我们把余下的写完
首先,我们先把扩展的View写了,扩展的View我是用的自定义的View,其实也就是几张图片而已啦,继承UIView自定义一个View
我的想法是,封装一个view,传入一个数组,就能显示一排间隔相等的图片,我定义的时每一行有4个button,有5个间隔,每个间隔的距离就应该是屏幕总宽度减去4*button的宽度在除以5,这样创建button,在给button绑定tag,方便知道是点击了哪个button
然后用代理讲点击了哪个button传回自定义的View去处理,大家也可以修改我的源码去适应自己的项目
BCMoreView.h文件
BCMoreView.m文件
好,更多view也写好了,现在我们回到keyboardView,将这个自定义的View加上去
keyboardView.m文件
其实显示扩展键盘和显示表情键盘是一样的,只不过要多传个数组,告诉自定义的View,你要显示什么,我的想法是,这个显示什么应该使用者自己去决定,所以我决定提供个外部接口,让使用者自己去传入什么样的数组,占位文字和文字颜色也让使用者自己去定义
在BCKeyBoard.h文件中加一个叫imageArray的数组属性
其实上次封装的键盘有个小bug,大家都没有发现吗(估计大家都去下载之后就直接用了,也不看是怎么封装的了,太伤我心了....,我还是希望大家一步一步的看下去,不懂的地方就在评论里问)
其实解决这个bug很简单,就是在textView刚开始编辑时,将2个按钮的selected都变成NO,底部的activeView置成nil
接下来就是最重要的了,将文字和表情传入到控制器中,我用的是代理传值,表情的处理是网上找的,那什么时候将值传到控制器呢,我的做法和QQ是一样的,将return键变成发送键,在textView的代理方法
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text中,那怎么判断点了发送键呢,其实就是判断换行,点击发送键就是换行字符
在发送后要将textView的内容置空,textView的高度也要随输入字符的多少改变高度,我的想法是传入textView,返回一个高度所以我就写了这个方法
但是光有这个方法是不够,还要有个改变整个view的frame和textView的frame的方法,我的想法是传入一个高度,就能随之改变view的frame和textView的frame,所以写了这个方法,_lastHeight代表上次的高度,因为textView的高度随着输入文字而改变,超过一行才改变高度,没超过一行还是上一次
的高度,代理方法是把高度返回给控制器
最后BCKeyBoard.h
BCKeyBoard.m
运行效果
基本封装好了,下一篇将封装点击moreView里面按钮的方法,顺便更新git库,敬请期待哦。
上次写到表情键盘,今天我们把余下的写完
首先,我们先把扩展的View写了,扩展的View我是用的自定义的View,其实也就是几张图片而已啦,继承UIView自定义一个View
我的想法是,封装一个view,传入一个数组,就能显示一排间隔相等的图片,我定义的时每一行有4个button,有5个间隔,每个间隔的距离就应该是屏幕总宽度减去4*button的宽度在除以5,这样创建button,在给button绑定tag,方便知道是点击了哪个button
然后用代理讲点击了哪个button传回自定义的View去处理,大家也可以修改我的源码去适应自己的项目
BCMoreView.h文件
#import <UIKit/UIKit.h> @protocol BCMoreViewDelegate <NSObject> - (void)didselectImageView:(NSInteger)index; @end @interface BCMoreView : UIView @property (nonatomic,strong)NSArray *imageArray; @property (nonatomic,weak)id <BCMoreViewDelegate> delegate; @end
BCMoreView.m文件
@implementation BCMoreView - (instancetype)initWithFrame:(CGRect)frame{ if(self = [super initWithFrame:frame]){ } return self; } - (void)setImageArray:(NSArray *)imageArray { CGFloat padding = ([UIScreen mainScreen].bounds.size.width - 42*4)/5; for(int i=0;i<imageArray.count;i++){ int clo = i % 4; int lin = i / 4; UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom]; btn.frame = CGRectMake(padding + (padding+42)*clo,20+(padding+42)*lin, 42, 42); btn.tag = i; [btn setBackgroundImage:[UIImage imageNamed:imageArray[i]] forState:UIControlStateNormal]; [btn addTarget:self action:@selector(selectImage:) forControlEvents:UIControlEventTouchUpInside]; [self addSubview:btn]; } } - (void)selectImage:(UIButton *)btn{ if(self.delegate){ [self.delegate didselectImageView:btn.tag]; } } @end
好,更多view也写好了,现在我们回到keyboardView,将这个自定义的View加上去
keyboardView.m文件
#import "BCKeyBoard.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> @property (nonatomic,strong)UIButton *faceBtn; @property (nonatomic,strong)UIButton *moreBtn; @property (nonatomic,strong)BCTextView *textView; @property (nonatomic,strong)UIImageView *backgroundImageView; @property (nonatomic,strong)UIView *faceView; @property (nonatomic,strong)UIView *activeView; @property (nonatomic,strong)UIView *moreView; @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{ //键盘高度改变是调用 [[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 = [UIColor lightGrayColor]; 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(willShowMoreView:) 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)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]; } - (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)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; } #pragma mark 表情键盘的代理方法 - (void)sendFace { } - (void)selectedFacialView:(NSString *)str isDelete:(BOOL)isDelete{ } //显示表情键盘 - (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]; } } //显示扩展键盘 - (void)willShowMoreView:(UIButton *)btn{ } //是点击了哪个图片 - (void)didselectImageView:(NSInteger)index { } @end
其实显示扩展键盘和显示表情键盘是一样的,只不过要多传个数组,告诉自定义的View,你要显示什么,我的想法是,这个显示什么应该使用者自己去决定,所以我决定提供个外部接口,让使用者自己去传入什么样的数组,占位文字和文字颜色也让使用者自己去定义
在BCKeyBoard.h文件中加一个叫imageArray的数组属性
#import "BCKeyBoard.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> @property (nonatomic,strong)UIButton *faceBtn; @property (nonatomic,strong)UIButton *moreBtn; @property (nonatomic,strong)BCTextView *textView; @property (nonatomic,strong)UIImageView *backgroundImageView; @property (nonatomic,strong)UIView *faceView; @property (nonatomic,strong)UIView *activeView; @property (nonatomic,strong)UIView *moreView; @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{ //键盘高度改变是调用 [[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 = [UIColor lightGrayColor]; 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(willShowMoreView:) 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)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]; } - (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)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; } #pragma mark 表情键盘的代理方法 - (void)sendFace { } - (void)selectedFacialView:(NSString *)str isDelete:(BOOL)isDelete{ } //显示表情键盘 - (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]; } } //显示扩展键盘 - (void)willShowMoreView:(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)didselectImageView:(NSInteger)index { } @end
其实上次封装的键盘有个小bug,大家都没有发现吗(估计大家都去下载之后就直接用了,也不看是怎么封装的了,太伤我心了....,我还是希望大家一步一步的看下去,不懂的地方就在评论里问)
其实解决这个bug很简单,就是在textView刚开始编辑时,将2个按钮的selected都变成NO,底部的activeView置成nil
- (void)textViewDidBeginEditing:(UITextView *)textView { [self willShowBottomView:nil]; self.faceBtn.selected = NO; self.moreBtn.selected = NO; }
接下来就是最重要的了,将文字和表情传入到控制器中,我用的是代理传值,表情的处理是网上找的,那什么时候将值传到控制器呢,我的做法和QQ是一样的,将return键变成发送键,在textView的代理方法
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text中,那怎么判断点了发送键呢,其实就是判断换行,点击发送键就是换行字符
在发送后要将textView的内容置空,textView的高度也要随输入字符的多少改变高度,我的想法是传入textView,返回一个高度所以我就写了这个方法
- (CGFloat)getTextViewContentH:(UITextView *)textView { return ceilf([textView sizeThatFits:textView.frame.size].height); }
但是光有这个方法是不够,还要有个改变整个view的frame和textView的frame的方法,我的想法是传入一个高度,就能随之改变view的frame和textView的frame,所以写了这个方法,_lastHeight代表上次的高度,因为textView的高度随着输入文字而改变,超过一行才改变高度,没超过一行还是上一次
的高度,代理方法是把高度返回给控制器
- (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]; } } }
最后BCKeyBoard.h
#import <UIKit/UIKit.h> @protocol BCKeyBoardDelegate <NSObject> /** 发送的文字 */ - (void)didSendText:(NSString *)text; /** 回调返回高度 */ - (void)returnHeight:(CGFloat)height; @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; /**< 占位文字颜色 */ @end
BCKeyBoard.m
#import "BCKeyBoard.h"
#import "BCTextView.h"
#import "Const.h"
#import "DXFaceView.h"
#import "BCMoreView.h"
@interface BCKeyBoard () <UITextViewDelegate,DXFaceDelegate,BCMoreViewDelegate>
@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,assign)BOOL isTop;
@property (nonatomic,strong)UIView *moreView;
@property (nonatomic,assign)CGFloat lastHeight;
//拓展的view
@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; }
- (void)willShowKeyboardFromFrame:(CGRect)beginFrame toFrame:(CGRect)toFrame
{
if (beginFrame.origin.y == [[UIScreen mainScreen] bounds].size.height)
{
[self willShowBottomHeight:toFrame.size.height];
if (self.activeView) {
[self.activeView removeFromSuperview];
}
self.activeView = nil;
}
else if(toFrame.origin.y == [[UIScreen mainScreen] bounds].size.height)
{
[self willShowBottomHeight:0];
}
else{
[self willShowBottomHeight:toFrame.size.height];
}
}
- (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
{
//这里是更多的view中选择了哪个图片
NSLog(@"%ld",(long)index);
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillChangeFrameNotification object:nil];
}
@end
运行效果
基本封装好了,下一篇将封装点击moreView里面按钮的方法,顺便更新git库,敬请期待哦。
相关文章推荐
- pivot列行转换,自动计算分组,解决groupby问题
- 事件注册 addEventListener 和 attachEvent区别
- TortoiseGit与github实现项目的上传
- iOS 获取设备唯一标示
- 我的Android进阶之旅------>Android关于Activity管理的一个简单封装
- 【codevs】p1169 传纸条
- svn cleanup failed–previous operation has not finished 解决方法
- 28. Element nodeValue 属性
- hdu2149巴什博弈
- Web API入门指南-安全篇
- android缓存框架ASimpleCache
- 查找练习 hash——出现过的数字
- RelativeLayout常用到的一些重要的属性:
- 微信接口整理
- 致歉信
- 选项卡的实现原理
- IE强制不使用兼容模式
- CentOs 6.3_64静默安装oracle11g_r2
- Ruby数组操作Tips
- 【map+字典序】hdu 4039 The Social Network