iOS开发之自定义表情键盘(组件封装与自动布局)

王朝学院·作者佚名  2016-08-27
窄屏简体版  字體: 小  |  中  |  大  |  超大  

下面的东西是编写自定义的表情键盘,话不多说,开门见山吧!下面主要用到的知识有MVC, iOS开发中的自动布局,自定义组件的封装与使用,Block回调,CoreData的使用。有的小伙伴可能会问写一个自定义表情键盘肿么这么麻烦?下面将会介绍我们如何用上面提到的东西来定义我们的表情键盘。下面的内容会比较多,这篇博文还是比较有料的。

还是那句话写技术博客是少不了代码的,下面会结合代码来回顾一下iOS的知识,本篇博文中用到的知识点在前面的博客中都能找到相应的内容,本篇算是一个小小的功能整合。先来张图看一下本app的目录结构。我是根据自己对MVC的理解来构建的目录结构,希望起到抛砖引玉的作用,有好的解决方案欢迎评论或者留言指出。Face文件中存放的时我们的表情图片,Model文件封装的是从sqlite中读取历史头像的组件,View文件中封装的时我们自定义的组件,也就是自定义键盘相关的视图,Controller负责将我们的各个组件组装到一起完成我们想要的功能。下面会一一介绍。

上面是文件的组织结构,下面为了更为直观的了解我们想要的效果,下面先看几张截图,来直观的感受一下运行效果,上面是竖屏的显示效果,下面是横屏的显示效果。因为在封装自定义键盘中用到了自动布局所以横屏显示或者在更大的屏幕上显示是没问题的,常用表情是用户用过的表情,然后存在Sqlite中,显示时并按时间降序排列。more是用来扩展功能用的接口。话不多说,来的代码才是实在的。

一.View(自定义视图)

View文件夹下存放的时我们自定义的视图组件,因为是自定义的组件所以storyboard我们就用不了啦,所有的代码都必须手写,这样才能保证组件使用的灵活性和减少各个组件之间的耦合性,更利于团队之间的合作。在封装组件时要预留好外界可能使用到的接口,和返回该返回的数据。好啦,废话少说,来点干货吧!

1、FaceView组件的封装:FaceView即负责显示一个个的头像。在使用该组件时要传入要显示的图片和图片对应的文字(如【哈哈】),当点击图片的时候,会通过block回调的形式把该图片的image以及图片文字返回到使用的组件中去,下面是关键代码:

FaceView.h中的代码如下(下面代码是定义啦相应的Block类型和对外的接口):

1#import<UIKit/UIKit.h>23//声明表情对应的block,用于把点击的表情的图片和图片信息传到上层视图4typedefvoid(^FaceBlock) (UIImage *image, NSString *imageText);56@interfaceFaceView : UIView78//图片对应的文字9@PRoperty (nonatomic, strong) NSString *imageText;10//表情图片11@property (nonatomic, strong) UIImage *headerImage;1213//设置block回调14-(void)setFaceBlock:(FaceBlock)block;1516//设置图片,文字17-(void)setImage:(UIImage *) image ImageText:(NSString *) text;1819@end

View Code

FaceView.m中的代码如下

1//2//FaceView.m3//MyKeyBoard4//5//Created by 青玉伏案 on 14-9-16.6//Copyright (c) 2014年 Mrli. All rights reserved.7//89#import"FaceView.h"1011@interfaceFaceView ()12@property(strong, nonatomic) FaceBlock block;13@property (strong, nonatomic) UIImageView *imageView;14@end1516@implementationFaceView1718//初始化图片19- (id)initWithFrame:(CGRect)frame20{21//face的大小22frame.size.height =30;23frame.size.width =30;24self =[super initWithFrame:frame];25if(self) {26self.imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0,0,30,30)];27[self addSubview:self.imageView];28}29returnself;30}3132-(void) setFaceBlock:(FaceBlock)block33{34self.block =block;35}363738-(void) setImage:(UIImage *)image ImageText:(NSString *)text39{40//显示图片41[self.imageView setImage:image];4243//把图片存储起来44self.headerImage =image;4546self.imageText =text;47}4849//点击时回调50-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event51{52UITouch *touch =[touches anyObject];53CGPoint point =[touch locationInView:self];54//判断触摸的结束点是否在图片中55if(CGRectContainsPoint(self.bounds, point))56{57//回调,把该头像的信息传到相应的controller中58self.block(self.headerImage, self.imageText);59}60}6162@end

View Code

代码说明:

主要就是block回调的使用,就是封装了一个自定义的button,具体内容请参考之前的博客“IOS开发之自定义Button(集成三种回调模式)”

2、FunctionView组件的封装,FunctionView就是使用FaceView组件和ScrollView组件把表情加载进来,在实例化FunctionView组件时,我们用到了自动布局来设置ScrollView和下面的Button

FunctionView.h的代码如下,在.h中留有组件的接口和回调用的Block, plistFileName用于加载我们的资源文件时使用,至于如何使用plist文件,请参考之前的博客:IOS开发之显示微博表情

1//2//FunctionView.h3//MyKeyBoard4//5//Created by 青玉伏案 on 14-9-16.6//Copyright (c) 2014年 Mrli. All rights reserved.7//89#import<UIKit/UIKit.h>1011//定义对应的block类型,用于数据的交互12typedefvoid(^FunctionBlock) (UIImage *image, NSString *imageText);1314@interfaceFunctionView : UIView15//资源文件名16@property (nonatomic, strong) NSString *plistFileName;17//接受block块18-(void)setFunctionBlock:(FunctionBlock) block;1920@end

View Code

FunctionView.m中的代码如下,常用表情是在sqlite中获取的,而全部表情是通过plist文件的信息在Face文件中加载的:

1//2//FunctionView.m3//MyKeyBoard4//5//Created by 青玉伏案 on 14-9-16.6//Copyright (c) 2014年 Mrli. All rights reserved.7//89#import"FunctionView.h"10#import"FaceView.h"11#import"ImageModelClass.h"12#import"HistoryImage.h"1314@interfaceFunctionView()1516@property (strong, nonatomic) FunctionBlock block;17//暂存表情组件回调的表情和表情文字18@property (strong, nonatomic) UIImage *headerImage;19@property (strong, nonatomic) NSString *imageText;2021//display我们的表情图片22@property (strong, nonatomic) UIScrollView *headerScrollView;2324//定义数据模型用于获取历史表情25@property (strong, nonatomic) ImageModelClass *imageModel;2627@end282930@implementationFunctionView31- (id)initWithFrame:(CGRect)frame32{33self =[super initWithFrame:frame];34if(self) {3536//实例化数据模型37self.imageModel =[[ImageModelClass alloc] init];3839//实例化下面的button40UIButton *faceButton =[[UIButton alloc] initWithFrame:CGRectZero];41faceButton.backgroundColor =[UIColor grayColor];4243[faceButton setTitle:@"全部表情"forState:UIControlStateNormal];44[faceButton setShowsTouchWhenHighlighted:YES];45[faceButton addTarget:self action:@selector(tapButton1:) forControlEvents:UIControlEventTouchUpInside];46[self addSubview:faceButton];474849//实例化常用表情按钮50UIButton *moreButton =[[UIButton alloc] initWithFrame:CGRectZero];51moreButton.backgroundColor =[UIColor orangeColor];52[moreButton setTitle:@"常用表情"forState:UIControlStateNormal];53[moreButton setShowsTouchWhenHighlighted:YES];54[moreButton addTarget:self action:@selector(tapButton2:) forControlEvents:UIControlEventTouchUpInside];55[self addSubview:moreButton];5657//给按钮添加约束58faceButton.translatesAutoresizingMaskIntoConstraints =NO;59moreButton.translatesAutoresizingMaskIntoConstraints =NO;60//水平约束61NSArray *buttonH = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[faceButton][moreButton(==faceButton)]|"options:0metrics:0views:NSDictionaryOfVariableBindings(faceButton,moreButton)];62[self addConstraints:buttonH];6364//垂直约束65NSArray *button1V = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[faceButton(44)]|"options:0metrics:0views:NSDictionaryOfVariableBindings(faceButton)];66[self addConstraints:button1V];6768NSArray *button2V = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[moreButton(44)]|"options:0metrics:0views:NSDictionaryOfVariableBindings(moreButton)];69[self addConstraints:button2V];7071//默认显示表情图片72[self tapButton1:nil];7374}75returnself;76}7778//接受回调79-(void)setFunctionBlock:(FunctionBlock)block80{81self.block =block;82}8384//点击全部表情按钮回调方法85-(void)tapButton1: (id) sender86{87//从plist文件载入资源88NSBundle *bundle =[NSBundle mainBundle];89NSString *path = [bundle pathForResource:self.plistFileName ofType:@"plist"];90NSArray *headers =[NSArray arrayWithContentsOfFile:path];9192if(headers.count ==0) {93NSLog(@"访问的plist文件不存在");94}95else96{97//调用headers方法显示表情98[self header:headers];99}100}101102//点击历史表情的回调方法103-(void) tapButton2: (id) sender104{105//从数据库中查询所有的图片106NSArray *imageData =[self.imageModel queryAll];107//解析请求到的数据108NSMutableArray *headers =[NSMutableArray arrayWithCapacity:imageData.count];109110//数据实体,相当于javaBean的东西111HistoryImage *tempData;112113for(inti =0; i < imageData.count; i ++) {114tempData =imageData[i];115116//解析数据,转换成函数headers要用的数据格式117NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithCapacity:2];118[dic setObject:tempData.imageText forKey:@"chs"];119UIImage *image =[UIImage imageWithData:tempData.headerImage];120[dic setObject:image forKey:@"png"];121122[headers addObject:dic];123}124125[self header:headers];126127}128129130//负责把查出来的图片显示131-(void) header:(NSArray *)headers132{133[self.headerScrollView removeFromSuperview];134self.headerScrollView =[[UIScrollView alloc] initWithFrame:CGRectZero];135[self addSubview:self.headerScrollView];136137//给scrollView添加约束138self.headerScrollView.translatesAutoresizingMaskIntoConstraints =NO;139//水平约束140NSArray *scrollH = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-10-[_headerScrollView]-10-|"options:0metrics:0views:NSDictionaryOfVariableBindings(_headerScrollView)];141[self addConstraints:scrollH];142143//垂直约束144NSArray *scrolV = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-10-[_headerScrollView]-50-|"options:0metrics:0views:NSDictionaryOfVariableBindings(_headerScrollView)];145[self addConstraints:scrolV];146147148149CGFloat scrollHeight = (self.frame).size.height-60;150151//根据图片量来计算scrollView的Contain的宽度152CGFloat width = (headers.count/(scrollHeight/30))*30;153self.headerScrollView.contentSize =CGSizeMake(width, scrollHeight);154self.headerScrollView.pagingEnabled =YES;155156157//图片坐标158CGFloat x =0;159CGFloat y =0;160161//往scroll上贴图片162for(inti =0; i < headers.count; i ++) {163//获取图片信息164UIImage *image;165if([headers[i][@"png"] isKindOfClass:[NSStringclass]])166{167image = [UIImage imageNamed:headers[i][@"png"]];168}169else170{171image = headers[i][@"png"];172}173174NSString *imageText = headers[i][@"chs"];175176//计算图片位置177y = (i%(int)(scrollHeight/30)) *30;178x = (i/(int)(scrollHeight/30)) *30;179180FaceView *face = [[FaceView alloc] initWithFrame:CGRectMake(x, y,0,0)];181[face setImage:image ImageText:imageText];182183//face的回调,当face点击时获取face的图片184__weak __block FunctionView *copy_self =self;185[face setFaceBlock:^(UIImage *image, NSString *imageText)186{187copy_self.block(image, imageText);188}];189190[self.headerScrollView addSubview:face];191}192193[self.headerScrollView setNeedsDisplay];194195}196197@end

View Code

代码说明:

1、主要是通过对资源文件或者对从数据库中查询的资源进行遍历然后添加到ScrollView中

2.为了适应不同的屏幕给相应的组件添加了约束

3.ToolView组件的封装: ToolView就是在主屏幕上下面的类似于TabBar的东西,当键盘出来的时候,ToolView会运动到键盘上面的位置。为了使用不同的屏幕,也需要用自动布局来实现。

ToolView.h的代码如下:预留组件接口和声明block类型

1//2//ToolView.h3//MyKeyBoard4//5//Created by 青玉伏案 on 14-9-16.6//Copyright (c) 2014年 Mrli. All rights reserved.7//89/*****************10封装下面的工具条组件11*****************/12#import<UIKit/UIKit.h>1314//定义block块变量类型,用于回调,把本View上的按钮的index传到Controller中15typedefvoid(^ToolIndex) (NSInteger index);1617@interfaceToolView : UIView1819//块变量类型的setter方法20-(void)setToolIndex:(ToolIndex) toolBlock;2122@end

View Code

ToolView.m的代码实现:

1//2//ToolView.m3//MyKeyBoard4//5//Created by 青玉伏案 on 14-9-16.6//Copyright (c) 2014年 Mrli. All rights reserved.7//89#import"ToolView.h"1011@interfaceToolView ()1213//定义ToolIndex类型的block,用于接受外界传过来的block14@property (nonatomic, strong) ToolIndex myBlock;1516@end171819@implementationToolView2021- (id)initWithFrame:(CGRect)frame22{23self =[super initWithFrame:frame];24if(self) {2526//1初始化表情按钮27UIButton *faceButton =[[UIButton alloc] initWithFrame:CGRectZero];28faceButton.backgroundColor =[UIColor orangeColor];29[faceButton setTitle:@"表情"forState:UIControlStateNormal];30[faceButton setShowsTouchWhenHighlighted:YES];31[faceButton addTarget:self action:@selector(tapFaceButton:) forControlEvents:UIControlEventTouchUpInside];32[self addSubview:faceButton];333435//初始化更多按钮36UIButton *moreButton =[[UIButton alloc] initWithFrame:CGRectZero];37moreButton.backgroundColor =[UIColor grayColor];38[moreButton setTitle:@"More"forState:UIControlStateNormal];39[moreButton setShowsTouchWhenHighlighted:YES];40[moreButton addTarget:self action:@selector(tapMoreButton:) forControlEvents:UIControlEventTouchUpInside];41[self addSubview:moreButton];424344//给我们的按钮添加约束来让按钮来占满toolView;45faceButton.translatesAutoresizingMaskIntoConstraints =NO;46moreButton.translatesAutoresizingMaskIntoConstraints =NO;4748//添加水平约束49NSArray *buttonH = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[faceButton][moreButton(==faceButton)]|"options:0metrics:0views:NSDictionaryOfVariableBindings(faceButton,moreButton)];50[self addConstraints:buttonH];5152//添加垂直约束53NSArray *button1V = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[faceButton]|"options:0metrics:0views:NSDictionaryOfVariableBindings(faceButton)];54[self addConstraints:button1V];5556NSArray *button2V = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[moreButton]|"options:0metrics:0views:NSDictionaryOfVariableBindings(moreButton)];57[self addConstraints:button2V];5859}60returnself;61}6263//接受传入的回调64-(void) setToolIndex:(ToolIndex)toolBlock65{66self.myBlock =toolBlock;67}6869//点击表情按钮要回调的方法70-(void) tapFaceButton: (id) sender71{72self.myBlock(1);73}7475//点击more要回调的方法76-(void) tapMoreButton: (id) sender77{78self.myBlock(2);79}8081@end

View Code

代码说明:

主要是对block回调的应用和给相应的组件添加相应的约束

4.MoreView组件的封装代码就不往上贴啦,和上面的类似,下面是调用MoreView组件的运行效果,有兴趣的读者请自行编写,以上就是视图部分的代码了

二. Mode部分的内容:

1.先定义我们要使用的数据模型,数据模型如下,time是使用表情的时间,用于排序。

2.下面编写我们的ImageModelClass类,里面封装了我们操作数据要用的方法

ImageModelClass.h的代码如下,主要是预留的对外的接口:

1//2//ImageModelClass.h3//MyKeyBoard4//5//Created by 青玉伏案 on 14-9-16.6//Copyright (c) 2014年 Mrli. All rights reserved.7//89#import<Foundation/Foundation.h>10#import<CoreData/CoreData.h>11#import"HistoryImage.h"1213@interfaceImageModelClass : NSObject14//保存数据15-(void)save:(NSData *) image ImageText:(NSString *) imageText;16//查询所有的图片17-(NSArray *) queryAll;18@end

View Code

ImageModelClass.m的代码如下,主要是用CoreData对sqlite的操作:

1//2//ImageModelClass.m3//MyKeyBoard4//5//Created by 青玉伏案 on 14-9-16.6//Copyright (c) 2014年 Mrli. All rights reserved.7//89#import"ImageModelClass.h"1011@interfaceImageModelClass ()1213@property (nonatomic, strong) NSManagedObjectContext *manager;1415@end1617@implementationImageModelClass18-(instancetype)init19{20self =[super init];21if(self) {22//通过上下文获取manager23UIapplication*application =[UIApplication sharedApplication];24iddelegate= application.delegate;25self.manager = [delegatemanagedObjectContext];26}27returnself;28}2930-(void)save:(NSData *)image ImageText:(NSString *)imageText31{32if(image !=nil) {33NSArray *result =[self search:imageText];3435HistoryImage *myImage;3637if(result.count ==0)38{39myImage = [NSEntityDescription insertNewObjectForEntityForName:NSStringFromClass([HistoryImageclass]) inManagedObjectContext:self.manager];40myImage.imageText =imageText;41myImage.headerImage =image;42myImage.time =[NSDate date];43}44else45{46myImage = result[0];47myImage.time =[NSDate date];48}4950//存储实体51NSError *error =nil;52if(![self.manager save:&error]) {53NSLog(@"保存出错%@", [error localizedDescription]);54}5556}5758}596061//查找62-(NSArray *)search:(NSString *) image63{64NSArray *result;6566//新建查询条件67NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:NSStringFromClass([HistoryImageclass])];6869//添加谓词70NSPredicate *predicate = [NSPredicate predicateWithFormat:@"imageText=%@",image];7172//把谓词给request73[fetchRequest setPredicate:predicate];7475//执行查询76NSError *error =nil;77result = [self.manager executeFetchRequest:fetchRequest error:&error];78if(error) {79NSLog(@"查询错误:%@", [error localizedDescription]);80}81returnresult;82}83848586//查询所有的87-(NSArray *) queryAll88{89//新建查询条件90NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:NSStringFromClass([HistoryImageclass])];9192//添加排序规则93//定义排序规则94NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"time"ascending:NO];9596//添加排序规则97[fetchRequest setSortDescriptors:@[sortDescriptor]];9899100//执行查询101NSError *error =nil;102NSArray *result = [self.manager executeFetchRequest:fetchRequest error:&error];103if(error) {104NSLog(@"查询错误:%@", [error localizedDescription]);105}106107returnresult;108}109110@end

View Code

代码说明:

1.保存图片时先查找图片是否存在,如果存在则更新时间,如果不存在则插入数据(写到这感觉想在用Hibernate写东西)。

三.Controller部分,把上面的组件进行组装

1.MainViewController.m中的延展部分的代码如下:

1@interfaceMainViewController ()23//自定义组件4@property (nonatomic, strong) ToolView *toolView;56@property (nonatomic, strong) FunctionView *functionView;78@property (nonatomic, strong) MoreView *moreView;910//系统组件11@property (strong, nonatomic) IBOutlet UITextView *myTextView;1213@property (strong, nonatomic) NSDictionary *keyBoardDic;1415@property (strong, nonatomic) IBOutlet UIImageView *imageView;1617@property (strong, nonatomic) NSString *sendString;1819//数据model20@property (strong, nonatomic) ImageModelClass *imageMode;2122@property (strong, nonatomic)HistoryImage *tempImage;2324@end

View Code

2.在viewDidLoad中进行组件的初始化和实现组件的Block回调,代码如下

1- (void)viewDidLoad2{3[super viewDidLoad];45//从sqlite中读取数据6self.imageMode =[[ImageModelClass alloc] init];789//实例化FunctionView10self.functionView = [[FunctionView alloc] initWithFrame:CGRectMake(0,0,320,216)];11self.functionView.backgroundColor =[UIColor blackColor];1213//设置资源加载的文件名14self.functionView.plistFileName =@"emoticons";1516__weak __block MainViewController *copy_self =self;17//获取图片并显示18[self.functionView setFunctionBlock:^(UIImage *image, NSString *imageText)19{20NSString *str = [NSString stringWithFormat:@"%@%@",copy_self.myTextView.text, imageText];2122copy_self.myTextView.text =str;23copy_self.imageView.image =image;2425//把使用过的图片存入sqlite26NSData *imageData =UIImagePNGRepresentation(image);27[copy_self.imageMode save:imageData ImageText:imageText];28}];293031//实例化MoreView32self.moreView = [[MoreView alloc] initWithFrame:CGRectMake(0,0,0,0)];33self.moreView.backgroundColor =[UIColor blackColor];34[self.moreView setMoreBlock:^(NSInteger index) {35NSLog(@"MoreIndex = %d",index);36}];37383940//进行ToolView的实例化41self.toolView =[[ToolView alloc] initWithFrame:CGRectZero];42self.toolView.backgroundColor =[UIColor blackColor];43[self.view addSubview:self.toolView];4445//给ToolView添加约束46//开启自动布局47self.toolView.translatesAutoresizingMaskIntoConstraints =NO;4849//水平约束50NSArray *toolHConstraint = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[_toolView]|"options:0metrics:0views:NSDictionaryOfVariableBindings(_toolView)];51[self.view addConstraints:toolHConstraint];5253//垂直约束54NSArray *toolVConstraint = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[_toolView(44)]|"options:0metrics:0views:NSDictionaryOfVariableBindings(_toolView)];55[self.view addConstraints:toolVConstraint];5657585960//回调toolView中的方法61[self.toolView setToolIndex:^(NSInteger index)62{63NSLog(@"%d", index);6465switch(index) {66case1:67[copy_self changeKeyboardToFunction];68

break;6970case2:71[copy_self changeKeyboardToMore];72

break;7374default:75

break;76}7778}];79808182//当键盘出来的时候通过通知来获取键盘的信息83//注册为键盘的监听着84NSNotificationCenter *center =[NSNotificationCenter defaultCenter];85[center addObserver:self selector:@selector(keyNotification:) name:UIKeyboardWillChangeFrameNotificationobject:nil];868788//给键盘添加dan89//TextView的键盘定制回收按钮90UIToolbar * toolBar = [[UIToolbar alloc]initWithFrame:CGRectMake(0,0,320,30)];9192UIBarButtonItem * item1 =[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(tapDone:)];93UIBarButtonItem * item2 =[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];94UIBarButtonItem * item3 =[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];95toolBar.items =@[item2,item1,item3];9697self.myTextView.inputaccessoryView =toolBar;9899}

View Code

3.当横竖屏幕切换时设置自定义键盘的高度

1-(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration2{3//纵屏4if(UIInterfaceOrientationIsPortrait(toInterfaceOrientation)) {5CGRect frame =self.functionView.frame;6frame.size.height =216;7self.functionView.frame =frame;8self.moreView.frame =frame;910}11//横屏12if(UIInterfaceOrientationIsLandscape(toInterfaceOrientation)) {13CGRect frame =self.functionView.frame;14frame.size.height =150;15self.functionView.frame =frame;16self.moreView.frame =frame;17}18}

View Code

4.当键盘出来的时候,改变toolView的位置,通过键盘的通知来实现。当横屏的时候键盘的坐标系和我们当前的Frame的坐标系不一样所以当横屏时得做一坐标系的转换,代码如下;

1//当键盘出来的时候改变toolView的位置(接到键盘出来的通知要做的方法)2-(void) keyNotification : (NSNotification *) notification3{4NSLog(@"%@", notification.userInfo);56self.keyBoardDic =notification.userInfo;7//获取键盘移动后的坐标点的坐标点8CGRect rect = [self.keyBoardDic[@"UIKeyboardFrameEndUserInfoKey"] CGRectValue];910//把键盘的坐标系改成当前我们window的坐标系11CGRect r1 =[self.view convertRect:rect fromView:self.view.window];1213[UIView animateWithDuration:[self.keyBoardDic[UIKeyboardAnimationDurationUserInfoKey] floatValue] animations:^{1415//动画曲线16[UIView setAnimationCurve:[self.keyBoardDic[UIKeyboardAnimationCurveUserInfoKey] doubleValue]];1718CGRect frame =self.toolView.frame;1920frame.origin.y = r1.origin.y -frame.size.height;2122//根据键盘的高度来改变toolView的高度23self.toolView.frame =frame;24}];25}

View Code

5.系统键盘和自定义键盘切换的代码如下:

1//切换键盘的方法2-(void) changeKeyboardToFunction3{4if([self.myTextView.inputView isEqual:self.functionView])5{6self.myTextView.inputView =nil;7[self.myTextView reloadInputViews];8}9else10{11self.myTextView.inputView =self.functionView;12[self.myTextView reloadInputViews];13}1415if(![self.myTextView isFirstResponder])16{17[self.myTextView becomeFirstResponder];18}19}

View Code

以上就是上面展示效果的核心代码了,在做的时候感觉难点在于如何进行屏幕适配,尤其是当屏幕横过来的时候键盘的坐标系和我们frame的坐标系不同,得做一个转换。发表博客的目的是想起到抛砖引玉的作用,有好的东西希望大家相互交流一下。笔者水平有限难免有偏颇之处,欢迎批评指正。

Demo地址:https://github.com/lizelu/WeChat

 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝網路 版權所有 導航