iOS組件封裝與自動布局自定義表情鍵盤
下面的東西是編寫自定義的表情鍵盤,話不多說,開門見山吧!下面主要用到的知識有MVC, iOS開發(fā)中的自動布局,自定義組件的封裝與使用,Block回調(diào),CoreData的使用。有的小伙伴可能會問寫一個自定義表情鍵盤腫么這么麻煩?下面 將會介紹我們?nèi)绾斡蒙厦嫣岬降臇|西來定義我們的表情鍵盤的。下面的內(nèi)容會比較多,這篇文章還是比較有料的。
還是那句話寫技術(shù)博客是少不了代碼的,下面會結(jié)合代碼來回顧一下iOS的知識,本篇博文中用到的知識點(diǎn)在前面的博客中都能找到相應(yīng)的內(nèi)容,本篇 算是一個小小的功能整合。先來張圖看一下本app的目錄結(jié)構(gòu)。我是根據(jù)自己對MVC的理解來構(gòu)建的目錄結(jié)構(gòu),希望起到拋磚引玉的作用,有好的解決方案歡迎 評論或者留言指出。Face文件中存放的時我們的表情圖片,Model文件封裝的是從sqlite中讀取歷史頭像的組件,View文件中封裝的時我們自定義的組件,也就是自定義鍵盤相關(guān)的視圖,Controller負(fù)責(zé)將我們的各個組件組裝到一起完成我們想要的功能。下面會一一介紹。

上面是文件的組織結(jié)構(gòu),下面為了更為直觀的了解我們想要的效果,下面先看幾張截圖,來直觀的感受一下運(yùn)行效果,上面是豎屏的顯示效果,下面是橫 屏的顯示效果。因?yàn)樵诜庋b自定義鍵盤中用到了自動布局所以橫屏顯示或者在更大的屏幕上顯示是沒問題的,常用表情是用戶用過的表情,然后存在Sqlite 中,顯示時并按時間降序排列。more是用來擴(kuò)展功能用的接口。話不多說,來的代碼才是實(shí)在的。

一.View(自定義視圖)
View文件夾下存放的時我們自定義的視圖組件,因?yàn)槭亲远x的組件所以storyboard我們就用不了啦,所有的代碼都必須手寫,這樣 才能保證組件使用的靈活性和減少各個組件之間的耦合性,更利于團(tuán)隊(duì)之間的合作。在封裝組件時要預(yù)留好外界可能使用到的接口,和返回該返回的數(shù)據(jù)。好啦,廢話少說,來點(diǎn)干貨吧!
1、FaceView組件的封裝:FaceView即負(fù)責(zé)顯示一個個的頭像。在使用該組件時要傳入要顯示的圖片和圖片對應(yīng)的文字(如【哈 哈】),當(dāng)點(diǎn)擊圖片的時候,會通過block回調(diào)的形式把該圖片的image以及圖片文字返回到使用的組件中去,下面是關(guān)鍵代碼:
FaceView.h中的代碼如下(下面代碼是定義啦相應(yīng)的Block類型和對外的接口):
#import //聲明表情對應(yīng)的block,用于把點(diǎn)擊的表情的圖片和圖片信息傳到上層視圖 typedef void (^FaceBlock) (UIImage *image, NSString *imageText); @interface FaceView : UIView //圖片對應(yīng)的文字 @property (nonatomic, strong) NSString *imageText; //表情圖片 @property (nonatomic, strong) UIImage *headerImage; //設(shè)置block回調(diào) -(void)setFaceBlock:(FaceBlock)block; //設(shè)置圖片,文字 -(void)setImage:(UIImage *) image ImageText:(NSString *) text; @end
FaceView.m中的代碼如下
// FaceView.m
// MyKeyBoard
//
// Created by 青玉伏案 on 14-9-16.
// Copyright (c) 2014年 Mrli. All rights reserved.
//
#import "FaceView.h"
@interface FaceView ()
@property(strong, nonatomic) FaceBlock block;
@property (strong, nonatomic) UIImageView *imageView;
@end
@implementation FaceView
//初始化圖片
- (id)initWithFrame:(CGRect)frame
{
//face的大小
frame.size.height = 30;
frame.size.width = 30;
self = [super initWithFrame:frame];
if (self) {
self.imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 30, 30)];
[self addSubview:self.imageView];
}
return self;
}
-(void) setFaceBlock:(FaceBlock)block
{
self.block = block;
}
-(void) setImage:(UIImage *)image ImageText:(NSString *)text
{
//顯示圖片
[self.imageView setImage:image];
//把圖片存儲起來
self.headerImage = image;
self.imageText = text;
}
//點(diǎn)擊時回調(diào)
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint point = [touch locationInView:self];
//判斷觸摸的結(jié)束點(diǎn)是否在圖片中
if (CGRectContainsPoint(self.bounds, point))
{
//回調(diào),把該頭像的信息傳到相應(yīng)的controller中
self.block(self.headerImage, self.imageText);
}
}
@end
代碼說明:
主要就是block回調(diào)的使用,就是封裝了一個自定義的button
2、FunctionView組件的封裝,F(xiàn)unctionView就是使用FaceView組件和ScrollView組件把表情加載進(jìn)來,在實(shí)例化FunctionView組件時,我們用到了自動布局來設(shè)置ScrollView和下面的Button.
FunctionView.h的代碼如下,在.h中留有組件的接口和回調(diào)用的Block, plistFileName用于加載我們的資源文件時使用。
// FunctionView.h // MyKeyBoard // // Created by 青玉伏案 on 14-9-16. // Copyright (c) 2014年 Mrli. All rights reserved. // #import //定義對應(yīng)的block類型,用于數(shù)據(jù)的交互 typedef void (^FunctionBlock) (UIImage *image, NSString *imageText); @interface FunctionView : UIView //資源文件名 @property (nonatomic, strong) NSString *plistFileName; //接受block塊 -(void)setFunctionBlock:(FunctionBlock) block; @end
FunctionView.m中的代碼如下,常用表情是在sqlite中獲取的,而全部表情是通過plist文件的信息在Face文件中加載的:
// FunctionView.m
// MyKeyBoard
//
// Created by 青玉伏案 on 14-9-16.
// Copyright (c) 2014年 Mrli. All rights reserved.
//
#import "FunctionView.h"
#import "FaceView.h"
#import "ImageModelClass.h"
#import "HistoryImage.h"
@interface FunctionView()
@property (strong, nonatomic) FunctionBlock block;
//暫存表情組件回調(diào)的表情和表情文字
@property (strong, nonatomic) UIImage *headerImage;
@property (strong, nonatomic) NSString *imageText;
//display我們的表情圖片
@property (strong, nonatomic) UIScrollView *headerScrollView;
//定義數(shù)據(jù)模型用于獲取歷史表情
@property (strong, nonatomic) ImageModelClass *imageModel;
@end
@implementation FunctionView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
//實(shí)例化數(shù)據(jù)模型
self.imageModel =[[ImageModelClass alloc] init];
//實(shí)例化下面的button
UIButton *faceButton = [[UIButton alloc] initWithFrame:CGRectZero];
faceButton.backgroundColor = [UIColor grayColor];
[faceButton setTitle:@"全部表情" forState:UIControlStateNormal];
[faceButton setShowsTouchWhenHighlighted:YES];
[faceButton addTarget:self action:@selector(tapButton1:) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:faceButton];
//實(shí)例化常用表情按鈕
UIButton *moreButton = [[UIButton alloc] initWithFrame:CGRectZero];
moreButton.backgroundColor = [UIColor orangeColor];
[moreButton setTitle:@"常用表情" forState:UIControlStateNormal];
[moreButton setShowsTouchWhenHighlighted:YES];
[moreButton addTarget:self action:@selector(tapButton2:) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:moreButton];
//給按鈕添加約束
faceButton.translatesAutoresizingMaskIntoConstraints = NO;
moreButton.translatesAutoresizingMaskIntoConstraints = NO;
//水平約束
NSArray *buttonH = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[faceButton][moreButton(==faceButton)]|" options:0 metrics:0 views:NSDictionaryOfVariableBindings(faceButton,moreButton)];
[self addConstraints:buttonH];
//垂直約束
NSArray *button1V = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[faceButton(44)]|" options:0 metrics:0 views:NSDictionaryOfVariableBindings(faceButton)];
[self addConstraints:button1V];
NSArray *button2V = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[moreButton(44)]|" options:0 metrics:0 views:NSDictionaryOfVariableBindings(moreButton)];
[self addConstraints:button2V];
//默認(rèn)顯示表情圖片
[self tapButton1:nil];
}
return self;
}
//接受回調(diào)
-(void)setFunctionBlock:(FunctionBlock)block
{
self.block = block;
}
//點(diǎn)擊全部表情按鈕回調(diào)方法
-(void)tapButton1: (id) sender
{
// 從plist文件載入資源
NSBundle *bundle = [NSBundle mainBundle];
NSString *path = [bundle pathForResource:self.plistFileName ofType:@"plist"];
NSArray *headers = [NSArray arrayWithContentsOfFile:path];
if (headers.count == 0) {
NSLog(@"訪問的plist文件不存在");
}
else
{
//調(diào)用headers方法顯示表情
[self header:headers];
}
}
//點(diǎn)擊歷史表情的回調(diào)方法
-(void) tapButton2: (id) sender
{
//從數(shù)據(jù)庫中查詢所有的圖片
NSArray *imageData = [self.imageModel queryAll];
//解析請求到的數(shù)據(jù)
NSMutableArray *headers = [NSMutableArray arrayWithCapacity:imageData.count];
//數(shù)據(jù)實(shí)體,相當(dāng)于javaBean的東西
HistoryImage *tempData;
for (int i = 0; i < imageData.count; i ++) {
tempData = imageData[i];
//解析數(shù)據(jù),轉(zhuǎn)換成函數(shù)headers要用的數(shù)據(jù)格式
NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithCapacity:2];
[dic setObject:tempData.imageText forKey:@"chs"];
UIImage *image = [UIImage imageWithData:tempData.headerImage];
[dic setObject:image forKey:@"png"];
[headers addObject:dic];
}
[self header:headers];
}
//負(fù)責(zé)把查出來的圖片顯示
-(void) header:(NSArray *)headers
{
[self.headerScrollView removeFromSuperview];
self.headerScrollView = [[UIScrollView alloc] initWithFrame:CGRectZero];
[self addSubview:self.headerScrollView];
//給scrollView添加約束
self.headerScrollView.translatesAutoresizingMaskIntoConstraints = NO;
//水平約束
NSArray *scrollH = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-10-[_headerScrollView]-10-|" options:0 metrics:0 views:NSDictionaryOfVariableBindings(_headerScrollView)];
[self addConstraints:scrollH];
//垂直約束
NSArray *scrolV = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-10-[_headerScrollView]-50-|" options:0 metrics:0 views:NSDictionaryOfVariableBindings(_headerScrollView)];
[self addConstraints:scrolV];
CGFloat scrollHeight = (self.frame).size.height-60;
//根據(jù)圖片量來計(jì)算scrollView的Contain的寬度
CGFloat width = (headers.count/(scrollHeight/30))*30;
self.headerScrollView.contentSize = CGSizeMake(width, scrollHeight);
self.headerScrollView.pagingEnabled = YES;
//圖片坐標(biāo)
CGFloat x = 0;
CGFloat y = 0;
//往scroll上貼圖片
for (int i = 0; i < headers.count; i ++) {
//獲取圖片信息
UIImage *image;
if ([headers[i][@"png"] isKindOfClass:[NSString class]])
{
image = [UIImage imageNamed:headers[i][@"png"]];
}
else
{
image = headers[i][@"png"];
}
NSString *imageText = headers[i][@"chs"];
//計(jì)算圖片位置
y = (i%(int)(scrollHeight/30)) * 30;
x = (i/(int)(scrollHeight/30)) * 30;
FaceView *face = [[FaceView alloc] initWithFrame:CGRectMake(x, y, 0, 0)];
[face setImage:image ImageText:imageText];
//face的回調(diào),當(dāng)face點(diǎn)擊時獲取face的圖片
__weak __block FunctionView *copy_self = self;
[face setFaceBlock:^(UIImage *image, NSString *imageText)
{
copy_self.block(image, imageText);
}];
[self.headerScrollView addSubview:face];
}
[self.headerScrollView setNeedsDisplay];
}
@end
代碼說明:
1、主要是通過對資源文件或者對從數(shù)據(jù)庫中查詢的資源進(jìn)行遍歷然后添加到ScrollView中
2.為了適應(yīng)不同的屏幕給相應(yīng)的組件添加了約束
3.ToolView組件的封裝: ToolView就是在主屏幕上下面的類似于TabBar的東西,當(dāng)鍵盤出來的時候,ToolView會運(yùn)動到鍵盤上面的位置。為了使用不同的屏幕,也需要用自動布局來實(shí)現(xiàn)。
ToolView.h的代碼如下:預(yù)留組件接口和聲明block類型
// ToolView.h
// MyKeyBoard
//
// Created by 青玉伏案 on 14-9-16.
// Copyright (c) 2014年 Mrli. All rights reserved.
//
/*****************
封裝下面的工具條組件
*****************/
#import //定義block塊變量類型,用于回調(diào),把本View上的按鈕的index傳到Controller中
typedef void (^ToolIndex) (NSInteger index);
@interface ToolView : UIView
//塊變量類型的setter方法
-(void)setToolIndex:(ToolIndex) toolBlock;
@end
ToolView.m的代碼實(shí)現(xiàn):
// ToolView.m
// MyKeyBoard
//
// Created by 青玉伏案 on 14-9-16.
// Copyright (c) 2014年 Mrli. All rights reserved.
//
#import "ToolView.h"
@interface ToolView ()
//定義ToolIndex類型的block,用于接受外界傳過來的block
@property (nonatomic, strong) ToolIndex myBlock;
@end
@implementation ToolView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
//1初始化表情按鈕
UIButton *faceButton = [[UIButton alloc] initWithFrame:CGRectZero];
faceButton.backgroundColor = [UIColor orangeColor];
[faceButton setTitle:@"表情" forState:UIControlStateNormal];
[faceButton setShowsTouchWhenHighlighted:YES];
[faceButton addTarget:self action:@selector(tapFaceButton:) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:faceButton];
//初始化更多按鈕
UIButton *moreButton = [[UIButton alloc] initWithFrame:CGRectZero];
moreButton.backgroundColor = [UIColor grayColor];
[moreButton setTitle:@"More" forState:UIControlStateNormal];
[moreButton setShowsTouchWhenHighlighted:YES];
[moreButton addTarget:self action:@selector(tapMoreButton:) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:moreButton];
//給我們的按鈕添加約束來讓按鈕來占滿toolView;
faceButton.translatesAutoresizingMaskIntoConstraints = NO;
moreButton.translatesAutoresizingMaskIntoConstraints = NO;
//添加水平約束
NSArray *buttonH = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[faceButton][moreButton(==faceButton)]|" options:0 metrics:0 views:NSDictionaryOfVariableBindings(faceButton,moreButton)];
[self addConstraints:buttonH];
//添加垂直約束
NSArray *button1V = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[faceButton]|" options:0 metrics:0 views:NSDictionaryOfVariableBindings(faceButton)];
[self addConstraints:button1V];
NSArray *button2V = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[moreButton]|" options:0 metrics:0 views:NSDictionaryOfVariableBindings(moreButton)];
[self addConstraints:button2V];
}
return self;
}
//接受傳入的回調(diào)
-(void) setToolIndex:(ToolIndex)toolBlock
{
self.myBlock = toolBlock;
}
//點(diǎn)擊表情按鈕要回調(diào)的方法
-(void) tapFaceButton: (id) sender
{
self.myBlock(1);
}
//點(diǎn)擊more要回調(diào)的方法
-(void) tapMoreButton: (id) sender
{
self.myBlock(2);
}
@end
代碼說明:
主要是對block回調(diào)的應(yīng)用和給相應(yīng)的組件添加相應(yīng)的約束。
4.MoreView組件的封裝代碼就不往上貼啦,和上面的類似,下面是調(diào)用MoreView組件的運(yùn)行效果,有興趣的讀者請自行編寫,以上就是視圖部分的代碼了

二. Mode部分的內(nèi)容
1.先定義我們要使用的數(shù)據(jù)模型,數(shù)據(jù)模型如下,time是使用表情的時間,用于排序。

2.下面編寫我們的ImageModelClass類,里面封裝了我們操作數(shù)據(jù)要用的方法
ImageModelClass.h的代碼如下,主要是預(yù)留的對外的接口:
// // ImageModelClass.h // MyKeyBoard // // Created by 青玉伏案 on 14-9-16. // Copyright (c) 2014年 Mrli. All rights reserved. // #import #import #import "HistoryImage.h" @interface ImageModelClass : NSObject //保存數(shù)據(jù) -(void)save:(NSData *) image ImageText:(NSString *) imageText; //查詢所有的圖片 -(NSArray *) queryAll; @end
ImageModelClass.m的代碼如下,主要是用CoreData對sqlite的操作:
// ImageModelClass.m
// MyKeyBoard
//
// Created by 青玉伏案 on 14-9-16.
// Copyright (c) 2014年 Mrli. All rights reserved.
//
#import "ImageModelClass.h"
@interface ImageModelClass ()
@property (nonatomic, strong) NSManagedObjectContext *manager;
@end
@implementation ImageModelClass
- (instancetype)init
{
self = [super init];
if (self) {
//通過上下文獲取manager
UIApplication *application = [UIApplication sharedApplication];
id delegate = application.delegate;
self.manager = [delegate managedObjectContext];
}
return self;
}
-(void)save:(NSData *)image ImageText:(NSString *)imageText
{
if (image != nil) {
NSArray *result = [self search:imageText];
HistoryImage *myImage;
if (result.count == 0)
{
myImage = [NSEntityDescription insertNewObjectForEntityForName:NSStringFromClass([HistoryImage class]) inManagedObjectContext:self.manager];
myImage.imageText = imageText;
myImage.headerImage = image;
myImage.time = [NSDate date];
}
else
{
myImage = result[0];
myImage.time = [NSDate date];
}
//存儲實(shí)體
NSError *error = nil;
if (![self.manager save:&error]) {
NSLog(@"保存出錯%@", [error localizedDescription]);
}
}
}
//查找
-(NSArray *)search:(NSString *) image
{
NSArray *result;
//新建查詢條件
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:NSStringFromClass([HistoryImage class])];
//添加謂詞
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"imageText=%@",image];
//把謂詞給request
[fetchRequest setPredicate:predicate];
//執(zhí)行查詢
NSError *error = nil;
result = [self.manager executeFetchRequest:fetchRequest error:&error];
if (error) {
NSLog(@"查詢錯誤:%@", [error localizedDescription]);
}
return result;
}
//查詢所有的
-(NSArray *) queryAll
{
//新建查詢條件
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:NSStringFromClass([HistoryImage class])];
//添加排序規(guī)則
//定義排序規(guī)則
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"time" ascending:NO];
//添加排序規(guī)則
[fetchRequest setSortDescriptors:@[sortDescriptor]];
//執(zhí)行查詢
NSError *error = nil;
NSArray *result = [self.manager executeFetchRequest:fetchRequest error:&error];
if (error) {
NSLog(@"查詢錯誤:%@", [error localizedDescription]);
}
return result;
}
@end
代碼說明:
1.保存圖片時先查找圖片是否存在,如果存在則更新時間,如果不存在則插入數(shù)據(jù)(寫到這感覺想在用Hibernate寫東西)。
三.Controller部分,把上面的組件進(jìn)行組裝
1.MainViewController.m中的延展部分的代碼如下:
@interface MainViewController () //自定義組件 @property (nonatomic, strong) ToolView *toolView; @property (nonatomic, strong) FunctionView *functionView; @property (nonatomic, strong) MoreView *moreView; //系統(tǒng)組件 @property (strong, nonatomic) IBOutlet UITextView *myTextView; @property (strong, nonatomic) NSDictionary *keyBoardDic; @property (strong, nonatomic) IBOutlet UIImageView *imageView; @property (strong, nonatomic) NSString *sendString; //數(shù)據(jù)model @property (strong, nonatomic) ImageModelClass *imageMode; @property (strong, nonatomic)HistoryImage *tempImage; @end
2.在viewDidLoad中進(jìn)行組件的初始化和實(shí)現(xiàn)組件的Block回調(diào),代碼如下
- (void)viewDidLoad
{
[super viewDidLoad];
//從sqlite中讀取數(shù)據(jù)
self.imageMode = [[ImageModelClass alloc] init];
//實(shí)例化FunctionView
self.functionView = [[FunctionView alloc] initWithFrame:CGRectMake(0, 0, 320, 216)];
self.functionView.backgroundColor = [UIColor blackColor];
//設(shè)置資源加載的文件名
self.functionView.plistFileName = @"emoticons";
__weak __block MainViewController *copy_self = self;
//獲取圖片并顯示
[self.functionView setFunctionBlock:^(UIImage *image, NSString *imageText)
{
NSString *str = [NSString stringWithFormat:@"%@%@",copy_self.myTextView.text, imageText];
copy_self.myTextView.text = str;
copy_self.imageView.image = image;
//把使用過的圖片存入sqlite
NSData *imageData = UIImagePNGRepresentation(image);
[copy_self.imageMode save:imageData ImageText:imageText];
}];
//實(shí)例化MoreView
self.moreView = [[MoreView alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
self.moreView.backgroundColor = [UIColor blackColor];
[self.moreView setMoreBlock:^(NSInteger index) {
NSLog(@"MoreIndex = %d",index);
}];
//進(jìn)行ToolView的實(shí)例化
self.toolView = [[ToolView alloc] initWithFrame:CGRectZero];
self.toolView.backgroundColor = [UIColor blackColor];
[self.view addSubview:self.toolView];
//給ToolView添加約束
//開啟自動布局
self.toolView.translatesAutoresizingMaskIntoConstraints = NO;
//水平約束
NSArray *toolHConstraint = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[_toolView]|" options:0 metrics:0 views:NSDictionaryOfVariableBindings(_toolView)];
[self.view addConstraints:toolHConstraint];
//垂直約束
NSArray *toolVConstraint = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[_toolView(44)]|" options:0 metrics:0 views:NSDictionaryOfVariableBindings(_toolView)];
[self.view addConstraints:toolVConstraint];
//回調(diào)toolView中的方法
[self.toolView setToolIndex:^(NSInteger index)
{
NSLog(@"%d", index);
switch (index) {
case 1:
[copy_self changeKeyboardToFunction];
break;
case 2:
[copy_self changeKeyboardToMore];
break;
default:
break;
}
}];
//當(dāng)鍵盤出來的時候通過通知來獲取鍵盤的信息
//注冊為鍵盤的監(jiān)聽著
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
[center addObserver:self selector:@selector(keyNotification:) name:UIKeyboardWillChangeFrameNotification object:nil];
//給鍵盤添加dan
//TextView的鍵盤定制回收按鈕
UIToolbar * toolBar = [[UIToolbar alloc]initWithFrame:CGRectMake(0, 0, 320, 30)];
UIBarButtonItem * item1 = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(tapDone:)];
UIBarButtonItem * item2 = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
UIBarButtonItem * item3 = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
toolBar.items = @[item2,item1,item3];
self.myTextView.inputAccessoryView =toolBar;
}
3.當(dāng)橫豎屏幕切換時設(shè)置自定義鍵盤的高度
-(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
//縱屏
if (UIInterfaceOrientationIsPortrait(toInterfaceOrientation)) {
CGRect frame = self.functionView.frame;
frame.size.height = 216;
self.functionView.frame = frame;
self.moreView.frame = frame;
}
//橫屏
if (UIInterfaceOrientationIsLandscape(toInterfaceOrientation)) {
CGRect frame = self.functionView.frame;
frame.size.height = 150;
self.functionView.frame = frame;
self.moreView.frame = frame;
}
}
4.當(dāng)鍵盤出來的時候,改變toolView的位置,通過鍵盤的通知來實(shí)現(xiàn)。當(dāng)橫屏的時候鍵盤的坐標(biāo)系和我們當(dāng)前的Frame的坐標(biāo)系不一樣所以當(dāng)橫屏?xí)r得做一坐標(biāo)系的轉(zhuǎn)換,代碼如下:
//當(dāng)鍵盤出來的時候改變toolView的位置(接到鍵盤出來的通知要做的方法)
-(void) keyNotification : (NSNotification *) notification
{
NSLog(@"%@", notification.userInfo);
self.keyBoardDic = notification.userInfo;
//獲取鍵盤移動后的坐標(biāo)點(diǎn)的坐標(biāo)點(diǎn)
CGRect rect = [self.keyBoardDic[@"UIKeyboardFrameEndUserInfoKey"] CGRectValue];
//把鍵盤的坐標(biāo)系改成當(dāng)前我們window的坐標(biāo)系
CGRect r1 = [self.view convertRect:rect fromView:self.view.window];
[UIView animateWithDuration:[self.keyBoardDic[UIKeyboardAnimationDurationUserInfoKey] floatValue] animations:^{
//動畫曲線
[UIView setAnimationCurve:[self.keyBoardDic[UIKeyboardAnimationCurveUserInfoKey] doubleValue]];
CGRect frame = self.toolView.frame;
frame.origin.y = r1.origin.y - frame.size.height;
//根據(jù)鍵盤的高度來改變toolView的高度
self.toolView.frame = frame;
}];
}
5.系統(tǒng)鍵盤和自定義鍵盤切換的代碼如下:
//切換鍵盤的方法
-(void) changeKeyboardToFunction
{
if ([self.myTextView.inputView isEqual:self.functionView])
{
self.myTextView.inputView = nil;
[self.myTextView reloadInputViews];
}
else
{
self.myTextView.inputView = self.functionView;
[self.myTextView reloadInputViews];
}
if (![self.myTextView isFirstResponder])
{
[self.myTextView becomeFirstResponder];
}
}
以上就是上面展示效果的核心代碼了,在做的時候感覺難點(diǎn)在于如何進(jìn)行屏幕適配,尤其是當(dāng)屏幕橫過來的時候鍵盤的坐標(biāo)系和我們frame的坐標(biāo)系不同,得做 一個轉(zhuǎn)換。發(fā)表文章的目的是想起到拋磚引玉的左右,有好的東西希望大家相互交流一下。
相關(guān)文章
詳解iOS應(yīng)用中自定義UIBarButtonItem導(dǎo)航按鈕的創(chuàng)建方法
這篇文章主要介紹了iOS應(yīng)用中自定義UIBarButtonItem導(dǎo)航按鈕的創(chuàng)建方法,文中舉了一個自定義圖片的UIBarButtonItem實(shí)例,比較具有代表性,需要的朋友可以參考下2016-04-04
iOS使用音頻處理框架The Amazing Audio Engine實(shí)現(xiàn)音頻錄制播放
這篇文章主要為大家詳細(xì)介紹了iOS使用音頻處理框架The Amazing Audio Engine實(shí)現(xiàn)音頻錄制播放,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-04-04
ios UITableView實(shí)現(xiàn)無數(shù)據(jù)加載占位圖片
這篇文章主要介紹了ios UITableView實(shí)現(xiàn)無數(shù)據(jù)占位圖片,具有一定的參考價(jià)值,有興趣的可以了解一下2017-08-08
iOS框架AVFoundation實(shí)現(xiàn)相機(jī)拍照、錄制視頻
這篇文章主要為大家詳細(xì)介紹了iOS框架AVFoundation實(shí)現(xiàn)相機(jī)拍照、錄制視頻功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-05-05

