zoukankan      html  css  js  c++  java
  • 带大家一步一步封装一个聊天键盘(二)

      继上次写了封装聊天键盘(一)地址(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文件

    #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:@"
    "]) {
            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库,敬请期待哦。

  • 相关阅读:
    Codeforces Round #276 (Div. 1) D. Kindergarten dp
    Codeforces Round #221 (Div. 1) B. Maximum Submatrix 2 dp排序
    hihoCoder Challenge 27 #1469 : 福字 dp
    Codeforces Beta Round #5 C. Longest Regular Bracket Sequence 括号序列 dp+栈
    Python id() 函数
    Python divmod() 函数
    Python any() 函数
    Python next() 函数
    Python slice() 函数
    Python3 hex() 函数
  • 原文地址:https://www.cnblogs.com/bcblogs/p/4707512.html
Copyright © 2011-2022 走看看