配色: 字号:
iOS组件封装与自动布局自定义表情键盘
2016-11-04 | 阅:  转:  |  分享 
  
iOS组件封装与自动布局自定义表情键盘

这篇文章主要介绍了iOS组件封装与自动布局自定义表情键盘的相关资料,需要的朋友可以参考下

下面的东西是编写自定义的表情键盘,话不多说,开门见山吧!下面主要用到的知识有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

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17 #import//声明表情对应的block,用于把点击的表情的图片和图片信息传到上层视图

typedefvoid(^FaceBlock)(UIImageimage,NSStringimageText);

@interfaceFaceView:UIView

//图片对应的文字

@property(nonatomic,strong)NSStringimageText;

//表情图片

@property(nonatomic,strong)UIImageheaderImage;

//设置block回调

-(void)setFaceBlock:(FaceBlock)block;

//设置图片,文字

-(void)setImage:(UIImage)imageImageText:(NSString)text;

@end 1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61 //FaceView.m

//MyKeyBoard

//

//Createdby青玉伏案on14-9-16.

//Copyright(c)2014年Mrli.Allrightsreserved.

//

#import"FaceView.h"

@interfaceFaceView()

@property(strong,nonatomic)FaceBlockblock;

@property(strong,nonatomic)UIImageViewimageView;

@end

@implementationFaceView

//初始化图片

-(id)initWithFrame:(CGRect)frame

{

//face的大小

frame.size.height=30;

frame.size.width=30;

self=[superinitWithFrame:frame];

if(self){

self.imageView=[[UIImageViewalloc]initWithFrame:CGRectMake(0,0,30,30)];

[selfaddSubview:self.imageView];

}

returnself;

}

-(void)setFaceBlock:(FaceBlock)block

{

self.block=block;

}

-(void)setImage:(UIImage)imageImageText:(NSString)text

{

//显示图片

[self.imageViewsetImage:image];

//把图片存储起来

self.headerImage=image;

self.imageText=text;

}

//点击时回调

-(void)touchesEnded:(NSSet)toucheswithEvent:(UIEvent)event

{

UITouchtouch=[touchesanyObject];

CGPointpoint=[touchlocationInView:self];

//判断触摸的结束点是否在图片中

if(CGRectContainsPoint(self.bounds,point))

{

//回调,把该头像的信息传到相应的controller中

self.block(self.headerImage,self.imageText);

}

}

@end 1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17 //FunctionView.h

//MyKeyBoard

//

//Createdby青玉伏案on14-9-16.

//Copyright(c)2014年Mrli.Allrightsreserved.

//

#import//定义对应的block类型,用于数据的交互

typedefvoid(^FunctionBlock)(UIImageimage,NSStringimageText);

@interfaceFunctionView:UIView

//资源文件名

@property(nonatomic,strong)NSStringplistFileName;

//接受block块

-(void)setFunctionBlock:(FunctionBlock)block;

@end 1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196 //FunctionView.m

//MyKeyBoard

//

//Createdby青玉伏案on14-9-16.

//Copyright(c)2014年Mrli.Allrightsreserved.

//

#import"FunctionView.h"

#import"FaceView.h"

#import"ImageModelClass.h"

#import"HistoryImage.h"

@interfaceFunctionView()

@property(strong,nonatomic)FunctionBlockblock;

//暂存表情组件回调的表情和表情文字

@property(strong,nonatomic)UIImageheaderImage;

@property(strong,nonatomic)NSStringimageText;

//display我们的表情图片

@property(strong,nonatomic)UIScrollViewheaderScrollView;

//定义数据模型用于获取历史表情

@property(strong,nonatomic)ImageModelClassimageModel;

@end

@implementationFunctionView

-(id)initWithFrame:(CGRect)frame

{

self=[superinitWithFrame:frame];

if(self){

//实例化数据模型

self.imageModel=[[ImageModelClassalloc]init];

//实例化下面的button

UIButtonfaceButton=[[UIButtonalloc]initWithFrame:CGRectZero];

faceButton.backgroundColor=[UIColorgrayColor];

[faceButtonsetTitle:@"全部表情"forState:UIControlStateNormal];

[faceButtonsetShowsTouchWhenHighlighted:YES];

[faceButtonaddTarget:selfaction:@selector(tapButton1:)forControlEvents:UIControlEventTouchUpInside];

[selfaddSubview:faceButton];

//实例化常用表情按钮

UIButtonmoreButton=[[UIButtonalloc]initWithFrame:CGRectZero];

moreButton.backgroundColor=[UIColororangeColor];

[moreButtonsetTitle:@"常用表情"forState:UIControlStateNormal];

[moreButtonsetShowsTouchWhenHighlighted:YES];

[moreButtonaddTarget:selfaction:@selector(tapButton2:)forControlEvents:UIControlEventTouchUpInside];

[selfaddSubview:moreButton];

//给按钮添加约束

faceButton.translatesAutoresizingMaskIntoConstraints=NO;

moreButton.translatesAutoresizingMaskIntoConstraints=NO;

//水平约束

NSArraybuttonH=[NSLayoutConstraintconstraintsWithVisualFormat:@"H:|[faceButton][moreButton(==faceButton)]|"options:0metrics:0views:NSDictionaryOfVariableBindings(faceButton,moreButton)];

[selfaddConstraints:buttonH];

//垂直约束

NSArraybutton1V=[NSLayoutConstraintconstraintsWithVisualFormat:@"V:[faceButton(44)]|"options:0metrics:0views:NSDictionaryOfVariableBindings(faceButton)];

[selfaddConstraints:button1V];

NSArraybutton2V=[NSLayoutConstraintconstraintsWithVisualFormat:@"V:[moreButton(44)]|"options:0metrics:0views:NSDictionaryOfVariableBindings(moreButton)];

[selfaddConstraints:button2V];

//默认显示表情图片

[selftapButton1:nil];

}

returnself;

}

//接受回调

-(void)setFunctionBlock:(FunctionBlock)block

{

self.block=block;

}

//点击全部表情按钮回调方法

-(void)tapButton1:(id)sender

{

//从plist文件载入资源

NSBundlebundle=[NSBundlemainBundle];

NSStringpath=[bundlepathForResource:self.plistFileNameofType:@"plist"];

NSArrayheaders=[NSArrayarrayWithContentsOfFile:path];

if(headers.count==0){

NSLog(@"访问的plist文件不存在");

}

else

{

//调用headers方法显示表情

[selfheader:headers];

}

}

//点击历史表情的回调方法

-(void)tapButton2:(id)sender

{

//从数据库中查询所有的图片

NSArrayimageData=[self.imageModelqueryAll];

//解析请求到的数据

NSMutableArrayheaders=[NSMutableArrayarrayWithCapacity:imageData.count];

//数据实体,相当于javaBean的东西

HistoryImagetempData;

for(inti=0;i
tempData=imageData[i];

//解析数据,转换成函数headers要用的数据格式

NSMutableDictionarydic=[NSMutableDictionarydictionaryWithCapacity:2];

[dicsetObject:tempData.imageTextforKey:@"chs"];

UIImageimage=[UIImageimageWithData:tempData.headerImage];

[dicsetObject:imageforKey:@"png"];

[headersaddObject:dic];

}

[selfheader:headers];

}

//负责把查出来的图片显示

-(void)header:(NSArray)headers

{

[self.headerScrollViewremoveFromSuperview];

self.headerScrollView=[[UIScrollViewalloc]initWithFrame:CGRectZero];

[selfaddSubview:self.headerScrollView];

//给scrollView添加约束

self.headerScrollView.translatesAutoresizingMaskIntoConstraints=NO;

//水平约束

NSArrayscrollH=[NSLayoutConstraintconstraintsWithVisualFormat:@"H:|-10-[_headerScrollView]-10-|"options:0metrics:0views:NSDictionaryOfVariableBindings(_headerScrollView)];

[selfaddConstraints:scrollH];

//垂直约束

NSArrayscrolV=[NSLayoutConstraintconstraintsWithVisualFormat:@"V:|-10-[_headerScrollView]-50-|"options:0metrics:0views:NSDictionaryOfVariableBindings(_headerScrollView)];

[selfaddConstraints:scrolV];

CGFloatscrollHeight=(self.frame).size.height-60;

//根据图片量来计算scrollView的Contain的宽度

CGFloatwidth=(headers.count/(scrollHeight/30))30;

self.headerScrollView.contentSize=CGSizeMake(width,scrollHeight);

self.headerScrollView.pagingEnabled=YES;

//图片坐标

CGFloatx=0;

CGFloaty=0;

//往scroll上贴图片

for(inti=0;i
//获取图片信息

UIImageimage;

if([headers[i][@"png"]isKindOfClass:[NSStringclass]])

{

image=[UIImageimageNamed:headers[i][@"png"]];

}

else

{

image=headers[i][@"png"];

}

NSStringimageText=headers[i][@"chs"];

//计算图片位置

y=(i%(int)(scrollHeight/30))30;

x=(i/(int)(scrollHeight/30))30;

FaceViewface=[[FaceViewalloc]initWithFrame:CGRectMake(x,y,0,0)];

[facesetImage:imageImageText:imageText];

//face的回调,当face点击时获取face的图片

__weak__blockFunctionViewcopy_self=self;

[facesetFaceBlock:^(UIImageimage,NSStringimageText)

{

copy_self.block(image,imageText);

}];

[self.headerScrollViewaddSubview:face];

}

[self.headerScrollViewsetNeedsDisplay];

}

@end 代码说明:

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

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

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

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101 //ToolView.h

//MyKeyBoard

//

//Createdby青玉伏案on14-9-16.

//Copyright(c)2014年Mrli.www.visa158.comAllrightsreserved.

//

/

封装下面的工具条组件

/

#import//定义block块变量类型,用于回调,把本View上的按钮的index传到Controller中

typedefvoid(^ToolIndex)(NSIntegerindex);

@interfaceToolView:UIView

//块变量类型的setter方法

-(void)setToolIndex:(ToolIndex)toolBlock;

@end

ToolView.m的代码实现:

//ToolView.m

//MyKeyBoard

//

//Createdby青玉伏案on14-9-16.

//Copyright(c)2014年Mrli.Allrightsreserved.

//

#import"ToolView.h"

@interfaceToolView()

//定义ToolIndex类型的block,用于接受外界传过来的block

@property(nonatomic,strong)ToolIndexmyBlock;

@end

@implementationToolView

-(id)initWithFrame:(CGRect)frame

{

self=[superinitWithFrame:frame];

if(self){

//1初始化表情按钮

UIButtonfaceButton=[[UIButtonalloc]initWithFrame:CGRectZero];

faceButton.backgroundColor=[UIColororangeColor];

[faceButtonsetTitle:@"表情"forState:UIControlStateNormal];

[faceButtonsetShowsTouchWhenHighlighted:YES];

[faceButtonaddTarget:selfaction:@selector(tapFaceButton:)forControlEvents:UIControlEventTouchUpInside];

[selfaddSubview:faceButton];

//初始化更多按钮

UIButtonmoreButton=[[UIButtonalloc]initWithFrame:CGRectZero];

moreButton.backgroundColor=[UIColorgrayColor];

[moreButtonsetTitle:@"More"forState:UIControlStateNormal];

[moreButtonsetShowsTouchWhenHighlighted:YES];

[moreButtonaddTarget:selfaction:@selector(tapMoreButton:)forControlEvents:UIControlEventTouchUpInside];

[selfaddSubview:moreButton];

//给我们的按钮添加约束来让按钮来占满toolView;

faceButton.translatesAutoresizingMaskIntoConstraints=NO;

moreButton.translatesAutoresizingMaskIntoConstraints=NO;

//添加水平约束

NSArraybuttonH=[NSLayoutConstraintconstraintsWithVisualFormat:@"H:|[faceButton][moreButton(==faceButton)]|"options:0metrics:0views:NSDictionaryOfVariableBindings(faceButton,moreButton)];

[selfaddConstraints:buttonH];

//添加垂直约束

NSArraybutton1V=[NSLayoutConstraintconstraintsWithVisualFormat:@"V:|[faceButton]|"options:0metrics:0views:NSDictionaryOfVariableBindings(faceButton)];

[selfaddConstraints:button1V];

NSArraybutton2V=[NSLayoutConstraintconstraintsWithVisualFormat:@"V:|[moreButton]|"options:0metrics:0views:NSDictionaryOfVariableBindings(moreButton)];

[selfaddConstraints:button2V];

}

returnself;

}

//接受传入的回调

-(void)setToolIndex:(ToolIndex)toolBlock

{

self.myBlock=toolBlock;

}

//点击表情按钮要回调的方法

-(void)tapFaceButton:(id)sender

{

self.myBlock(1);

}

//点击more要回调的方法

-(void)tapMoreButton:(id)sender

{

self.myBlock(2);

}

@end 代码说明:

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

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



二.Mode部分的内容

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



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

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16 //

//ImageModelClass.h

//MyKeyBoard

//

//Createdby青玉伏案on14-9-16.

//Copyright(c)2014年Mrli.Allrightsreserved.

//

#import#import#import"HistoryImage.h"

@interfaceImageModelClass:NSObject

//保存数据

-(void)save:(NSData)imageImageText:(NSString)imageText;

//查询所有的图片

-(NSArray)queryAll;

@end 1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109 //ImageModelClass.m

//MyKeyBoard

//

//Createdby青玉伏案on14-9-16.

//Copyright(c)2014年Mrli.Allrightsreserved.

//

#import"ImageModelClass.h"

@interfaceImageModelClass()

@property(nonatomic,strong)NSManagedObjectContextmanager;

@end

@implementationImageModelClass

-(instancetype)init

{

self=[superinit];

if(self){

//通过上下文获取manager

UIApplicationapplication=[UIApplicationsharedApplication];

iddelegate=application.delegate;

self.manager=[delegatemanagedObjectContext];

}

returnself;

}

-(void)save:(NSData)imageImageText:(NSString)imageText

{

if(image!=nil){

NSArrayresult=[selfsearch:imageText];

HistoryImagemyImage;

if(result.count==0)

{

myImage=[NSEntityDescriptioninsertNewObjectForEntityForName:NSStringFromClass([HistoryImageclass])inManagedObjectContext:self.manager];

myImage.imageText=imageText;

myImage.headerImage=image;

myImage.time=[NSDatedate];

}

else

{

myImage=result[0];

myImage.time=[NSDatedate];

}

//存储实体

NSErrorerror=nil;

if(![self.managersave:&error]){

NSLog(@"保存出错%@",[errorlocalizedDescription]);

}

}

}

//查找

-(NSArray)search:(NSString)image

{

NSArrayresult;

//新建查询条件

NSFetchRequestfetchRequest=[[NSFetchRequestalloc]initWithEntityName:NSStringFromClass([HistoryImageclass])];

//添加谓词

NSPredicatepredicate=[NSPredicatepredicateWithFormat:@"imageText=%@",image];

//把谓词给request

[fetchRequestsetPredicate:predicate];

//执行查询

NSErrorerror=nil;

result=[self.managerexecuteFetchRequest:fetchRequesterror:&error];

if(error){

NSLog(@"查询错误:%@",[errorlocalizedDescription]);

}

returnresult;

}

//查询所有的

-(NSArray)queryAll

{

//新建查询条件

NSFetchRequestfetchRequest=[[NSFetchRequestalloc]initWithEntityName:NSStringFromClass([HistoryImageclass])];

//添加排序规则

//定义排序规则

NSSortDescriptorsortDescriptor=[[NSSortDescriptoralloc]initWithKey:@"time"ascending:NO];

//添加排序规则

[fetchRequestsetSortDescriptors:@[sortDescriptor]];

//执行查询

NSErrorerror=nil;

NSArrayresult=[self.managerexecuteFetchRequest:fetchRequesterror:&error];

if(error){

NSLog(@"查询错误:%@",[errorlocalizedDescription]);

}

returnresult;

}

@end 代码说明:

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

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

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24 @interfaceMainViewController()

//自定义组件

@property(nonatomic,strong)ToolViewtoolView;

@property(nonatomic,strong)FunctionViewfunctionView;

@property(nonatomic,strong)MoreViewmoreView;

//系统组件

@property(strong,nonatomic)IBOutletUITextViewmyTextView;

@property(strong,nonatomic)NSDictionarykeyBoardDic;

@property(strong,nonatomic)IBOutletUIImageViewimageView;

@property(strong,nonatomic)NSStringsendString;

//数据model

@property(strong,nonatomic)ImageModelClassimageMode;

@property(strong,nonatomic)HistoryImagetempImage;

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99 -(void)viewDidLoad

{

[superviewDidLoad];

//从sqlite中读取数据

self.imageMode=[[ImageModelClassalloc]init];

//实例化FunctionView

self.functionView=[[FunctionViewalloc]initWithFrame:CGRectMake(0,0,320,216)];

self.functionView.backgroundColor=[UIColorblackColor];

//设置资源加载的文件名

self.functionView.plistFileName=@"emoticons";

__weak__blockMainViewControllercopy_self=self;

//获取图片并显示

[self.functionViewsetFunctionBlock:^(UIImageimage,NSStringimageText)

{

NSStringstr=[NSStringstringWithFormat:@"%@%@",copy_self.myTextView.text,imageText];

copy_self.myTextView.text=str;

copy_self.imageView.image=image;

//把使用过的图片存入sqlite

NSDataimageData=UIImagePNGRepresentation(image);

[copy_self.imageModesave:imageDataImageText:imageText];

}];

//实例化MoreView

self.moreView=[[MoreViewalloc]initWithFrame:CGRectMake(0,0,0,0)];

self.moreView.backgroundColor=[UIColorblackColor];

[self.moreViewsetMoreBlock:^(NSIntegerindex){

NSLog(@"MoreIndex=%d",index);

}];

//进行ToolView的实例化

self.toolView=[[ToolViewalloc]initWithFrame:CGRectZero];

self.toolView.backgroundColor=[UIColorblackColor];

[self.viewaddSubview:self.www.hunanwang.nettoolView];

//给ToolView添加约束

//开启自动布局

self.toolView.translatesAutoresizingMaskIntoConstraints=NO;

//水平约束

NSArraytoolHConstraint=[NSLayoutConstraintconstraintsWithVisualFormat:@"H:|[_toolView]|"options:0metrics:0views:NSDictionaryOfVariableBindings(_toolView)];

[self.viewaddConstraints:toolHConstraint];

//垂直约束

NSArraytoolVConstraint=[NSLayoutConstraintconstraintsWithVisualFormat:@"V:[_toolView(44)]|"options:0metrics:0views:NSDictionaryOfVariableBindings(_toolView)];

[self.viewaddConstraints:toolVConstraint];

//回调toolView中的方法

[self.toolViewsetToolIndex:^(NSIntegerindex)

{

NSLog(@"%d",index);

switch(index){

case1:

[copy_selfchangeKeyboardToFunction];

break;

case2:

[copy_selfchangeKeyboardToMore];

break;

default:

break;

}

}];

//当键盘出来的时候通过通知来获取键盘的信息

//注册为键盘的监听着

NSNotificationCentercenter=[NSNotificationCenterdefaultCenter];

[centeraddObserver:selfselector:@selector(keyNotification:)name:UIKeyboardWillChangeFrameNotificationobject:nil];

//给键盘添加dan

//TextView的键盘定制回收按钮

UIToolbartoolBar=[[UIToolbaralloc]initWithFrame:CGRectMake(0,0,320,30)];

UIBarButtonItemitem1=[[UIBarButtonItemalloc]initWithBarButtonSystemItem:UIBarButtonSystemItemDonetarget:selfaction:@selector(tapDone:)];

UIBarButtonItemitem2=[[UIBarButtonItemalloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpacetarget:nilaction:nil];

UIBarButtonItemitem3=[[UIBarButtonItemalloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpacetarget:nilaction:nil];

toolBar.items=@[item2,item1,item3];

self.myTextView.inputAccessoryView=toolBar;

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18 -(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientationduration:(NSTimeInterval)duration

{

//纵屏

if(UIInterfaceOrientationIsPortrait(toInterfaceOrientation)){

CGRectframe=self.functionView.frame;

frame.size.height=216;

self.functionView.frame=frame;

self.moreView.frame=frame;

}

//横屏

if(UIInterfaceOrientationIsLandscape(toInterfaceOrientation)){

CGRectframe=self.functionView.frame;

frame.size.height=150;

self.functionView.frame=frame;

self.moreView.frame=frame;

}

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25 //当键盘出来的时候改变toolView的位置(接到键盘出来的通知要做的方法)

-(void)keyNotification:(NSNotification)notification

{

NSLog(@"%@",notification.userInfo);

self.keyBoardDic=notification.userInfo;

//获取键盘移动后的坐标点的坐标点

CGRectrect=[self.keyBoardDic[@"UIKeyboardFrameEndUserInfoKey"]CGRectValue];

//把键盘的坐标系改成当前我们window的坐标系

CGRectr1=[self.viewconvertRect:rectfromView:self.view.window];

[UIViewanimateWithDuration:[self.keyBoardDic[UIKeyboardAnimationDurationUserInfoKey]floatValue]animations:^{

//动画曲线

[UIViewsetAnimationCurve:[self.keyBoardDic[UIKeyboardAnimationCurveUserInfoKey]doubleValue]];

CGRectframe=self.toolView.frame;

frame.origin.y=r1.origin.y-frame.size.height;

//根据键盘的高度来改变toolView的高度

self.toolView.frame=frame;

}];

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20 //切换键盘的方法

-(void)changeKeyboardToFunction

{

if([self.myTextView.inputViewisEqual:self.functionView])

{

self.myTextView.inputView=nil;

[self.myTextViewreloadInputViews];

}

else

{

self.myTextView.inputView=self.functionView;

[self.myTextViewreloadInputViews];

}

if(![self.myTextViewisFirstResponder])

{

[self.myTextViewbecomeFirstResponder];

}

} 以上就是上面展示效果的核心代码了,在做的时候感觉难点在于如何进行屏幕适配,尤其是当屏幕横过来的时候键盘的坐标系和我们frame的坐标系不同,得做一个转换。发表文章的目的是想起到抛砖引玉的左右,有好的东西希望大家相互交流一下。























献花(0)
+1
(本文系白狐一梦首藏)