IOS 简洁输入框的实现
我们在朋友圈,qq空间或微博的app看到这样的操作,点击回复,在视图的下面立即显示一个输入框。输入我们的文字后点击发送就可以。那么这个小小的输入框是怎么实现的呢
我也试着自己写了一个小小对话框,先看一下样式
主要的功能有
- 有一个placeholder的文字作为提示,点击输入文字后消失,当删除后文字为空的时候,重新出现。
- 文本框下面有一条蓝色线表示输入的框范围,类似我们微信里面的那个绿色的输入框
- 文本框需要跟随键盘上下浮动,再输入文字后能自动调整大小和位置
- 右边的发送按钮,在没有文字的时候是灰色的,提示无法发送,当输入文本框不为空的时候,可以发送,用蓝色来表示,而且需要根据左边的输入框高度变化而变化
- 顶部有一条和底部视图分界的线
- 在输入完成后,点击键盘的完成或者点击发送按钮能输出文字
通过功能区分我们可以大致将该视图分成三个部分,第一个是分割线,宽度为1的UIView
,第二个是类似html中的具有placeHolder功能的输入框,最后是按钮button。
输入文本框的实现
输入框是由UILabel
+UITextView
+UIImageView
(蓝色线)实现的,UITextView
的内容长度变化可以通过监听UITextViewTextDidChangeNotification
来判断当前输入框的输入字数。
先建一个类继承UITextView
添加placeText和placeColor到头文件由于外部改变placetext内容,现在添加UILable
-(void)PlaceTextLabel{
if (self.placeText.length>0) {
if (!_placeTextLab) {
CGRect frame=CGRectMake(8,8, self.bounds.size.width-16, 0);
_placeTextLab=[[UILabel alloc]initWithFrame:frame];
_placeTextLab.font=self.font;
_placeTextLab.backgroundColor=[UIColor clearColor];
_placeTextLab.textColor=self.placeColor;
_placeTextLab.tag=999;
_placeTextLab.alpha=0;
_placeTextLab.lineBreakMode=NSLineBreakByWordWrapping;
_placeTextLab.numberOfLines=0;
[self addSubview:_placeTextLab];
}
_placeTextLab.text=self.placeText;
[_placeTextLab sizeToFit];
[_placeTextLab setFrame:CGRectMake(8, 8, CGRectGetWidth(self.bounds)-16, CGRectGetHeight(_placeTextLab.frame))];
}
if (self.text.length==0 && self.placeText.length>0) {
[[self viewWithTag:999]setAlpha:1.0];
}
}
用Photoshop做一个单行像素的类似蓝线的图片,保存为png格式,必须设置图片的UIImageView
的图片显示模式
-(void)addLineView{
[_subLine removeFromSuperview];
_subLine=[[UIImageView alloc]initWithImage:[UIImage imageNamed:@"subline.png"]];
[_subLine setContentMode:UIViewContentModeScaleToFill];
[self addSubline:_subLine];
}
UITextView
的设置会相对麻烦一些,重写初始化代码
-(instancetype)initWithFrame:(CGRect)frame PlaceText:(NSString *)placeText PlaceColor:(UIColor *)placeColor{
self=[super initWithFrame:frame];
if (self) {
self.scrollEnabled=NO;
_placeText=placeText;
_placeColor=placeColor;
_Textnil=YES;
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(TextChange:) name:UITextViewTextDidChangeNotification object:nil];
}
return self;
}
由于输入框会随着输入的文字而不断增高,我们需要把这个值传递给父视图,让父视图也能根据内容而增大,可以通过委托来,但是委托又有点重量级,这里我们可以用更简单的block
这里首先我想到的是通过监听UITextViewTextDidChangeNotification
来实时监测输入,输入实时变化引起高度的实时变化。但是不幸的是我掉坑里了,我发现当我们输入一行到头以后再输入一个字符换行后,这个时候高度居然没有变。再输入这一行的第二个字符时候,高度值才发生变化。我想应该是高度变化之前,已经发送了通知所以导致我们的高度变化其实不是实时的,如果这样就不能用这种方式了,所幸的我们还可以使用UITextView
的一个简单函数
CGSize size= [self sizeThatFits:CGSizeMake(self.contentSize.width, 1000.0)];
这样size就是我们要的大小了。
-(void)TextChange:(NSNotification *)notification{
if (self.text.length==0) {
_Textnil=YES;
}else{
_Textnil=NO;
}
[self addLineView];
if (self.placeText.length==0) {
return;
}
[UIView animateWithDuration:0.5 animations:^{
if (_Textnil) {
[[self viewWithTag:999]setAlpha:1.0];
}else{
[[self viewWithTag:999] setAlpha:0];
}
}];
}
-(void)addSubline:(UIView *)view{
CGSize size= [self sizeThatFits:CGSizeMake(self.contentSize.width, 1000.0)];
if (view) {
CGRect frame=CGRectMake(2, size.height-3, self.bounds.size.width-4, 3.0);
view.frame=frame;
}
[self addSubview:view];
self.viewSize(size);//先判断一下更好。。。
}
这里使用block传递size,我们先声明一个block的私有变量,再写一个方法用来赋值,block的实现也是由调用该对象的类创建的。然后像委托一样调用就可以,AFNetwork中我们可以到处看到block而不像他的前辈ASIhttprequest到处是委托。
组装
主要的输入框完工后,就能组装了,先新建一个UIview子类。UIView需要和键盘高度保持一致。需要监听键盘滑出滑入的通知UIKeyboardWillChangeFrameNotification
,实时改变输入框的高度
-(void)keyboardWillShow:(NSNotification *)notification{
NSDictionary *userInfo=[notification userInfo];
NSTimeInterval boardAnimationDuration=[[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
CGRect frame=[[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey]CGRectValue];
[UIView animateWithDuration:boardAnimationDuration delay:0.0f options:UIViewAnimationOptionCurveEaseInOut animations:^{
CGFloat keyBoardY=frame.origin.y;
CGFloat keyBoardHeigh=frame.size.height;
maxy=[UIScreen mainScreen].bounds.size.height-keyBoardHeigh;
CGRect frame=self.frame;
frame.origin.y=keyBoardY-CGRectGetHeight(self.frame);
self.frame=frame;
} completion:^(BOOL finished) {
nil;
}];
}
这里的maxY是指输入框的y方向的标准位置。在没有键盘的情况下是[UIScreen mainScreen].bounds.size.height
,在有键盘的情况是键盘的y值,在输入框字符变化的时候实时改变他的高度
如下面图所示
-(void)TextViewDidChange:(CGSize)size{
self.frame=CGRectMake(0, self.frame.origin.y, self.frame.size.width,size.height+6*2);
self.frame=CGRectMake(0,maxy-self.frame.size.height, self.frame.size.width, self.frame.size.height);
_Inputview.frame=CGRectMake(10, 6, self.frame.size.width-K_right_padding, size.height);
}
以上是比较重要的UIView高度自适应变化的问题
这里button与外部类的调用关系也采用的是block的方式
@property (nonatomic,copy)void(^sendText)(NSString *);
-(void)sendMessage:(void (^)(NSString * text))inputText{
if (inputText) {
self.sendText=inputText;
}
}
-(void)buttonClick{
[self sendInputText];
}
-(void)sendInputText{
if (_Inputview.Textnil) {
return;
}else{
if(self.sendText){
self.sendText(_Inputview.text);
_Inputview.text=@"";
}
}
}
最后附上我的sourceCode,献给那些在ios道路上一起默默前进的小白们,我也是小白,求宽恕的对待O(∩_∩)O
IOS 简洁输入框的实现的更多相关文章
- (转载) Android 带清除功能的输入框控件ClearEditText,仿IOS的输入框
Android 带清除功能的输入框控件ClearEditText,仿IOS的输入框 标签: Android清除功能EditText仿IOS的输入框 2013-09-04 17:33 70865人阅读 ...
- Android 带清除功能的输入框控件ClearEditText,仿IOS的输入框
转载请注明出处http://blog.csdn.net/xiaanming/article/details/11066685 今天给大家带来一个很实用的小控件ClearEditText,就是在Andr ...
- 移动端项目在ios上输入框聚焦难解决方案
由于引入fastclick导致ios端input.textarea输入框难以点击聚焦,解决方案如下: 找到项目中的fastclick依赖或在main.js中改写fastclick的focus实现.
- vue 解决ios编辑器输入框不能拉起
一.问题描述:Android .pc.下可以正常使用,在ios下可以拉起输入框但是无法输入 <div contenteditable="true" ></div& ...
- iOS TextField输入框点击键盘时随着键盘上移
-(void)textFieldDidBeginEditing:(UITextField *)textField { CGRect frame = textField.frame; int offse ...
- ios - UISearchBar输入框背景色
//输入框背景色 bar.searchBarStyle = UISearchBarStyleMinimal; [bar positionAdjustmentForSearchBarIcon:UISea ...
- 表单在ios下输入框必须重压或长按才能唤起软键盘
解决方案: 一.在node_module里找到fastClick文件,然后找到focus方法,加一句focus方法即可解决:FastClick.prototype.focus = function(t ...
- iOS 控制输入框的字数?(textFliedView,textFlied等)
//控制输入框的字数 - (void)textViewDidChange:(UITextView *)textView { NSInteger number = [textView.text leng ...
- ios移动输入框被软键盘遮挡
页面输入框会出现被软键盘挡住的问题: 解决方法:获取input点击事件设置body高度 $('input').bind('click',function(e){ var $this = $(this) ...
随机推荐
- JS自定义去除字符串左右两边的指定字符
function ltrim(str,char){ var pos = str.indexOf(char); var sonstr = str.substr(pos+1); return sonstr ...
- element UI 的学习一,路由跳转
1.项目开始: # 安装vue $ cnpm install vue@2.1.6 # 全局安装 vue-cli $ cnpm install --global vue-cli ...
- dp之完全背包poj1787(完全背包以及路径记录 推荐)
题意:有四种硬币,1分,5分,10分,25分,分别有a,b,c,d种,给出一个n分钱,要求你求出组成n分钱最多需要的硬币数量,并且输出组成它的各种硬币的数量...... 学到的东西:这个题目我是用两种 ...
- matlab_legend_使用
matlab legend 使用 用Matlab画图时,有时候需要对各种图标进行标注,例如,用“+”代表A的运动情况,“*”代表B的 运动情况.legend函数的基本用法是LEGEND(string1 ...
- 【转载】PHP 常用的header头部定义汇总
header() 函数向客户端发送原始的 HTTP 报头. 认识到一点很重要,即必须在任何实际的输出被发送之前调用 header() 函数(在 PHP 4 以及更高的版本中,您可以使用输出缓存来解决此 ...
- base64变形注入与联合查询注入的爱情故事
先来写一下GET的知识点: 1.知道了convart函数(CONVERT函数是把日期转换为新数据类型的通用函数) 2.Illegal mix of collations for operation ' ...
- lua获取喜马拉雅音频地址
参考此文http://blog.csdn.net/zjg555543/article/details/39177971 在Linux下可以直接运行 #!/usr/bin/lua5. --需要luacu ...
- 详解 Go 语言中的 time.Duration 类型
swardsman详解 Go 语言中的 time.Duration 类型swardsman · 2018-03-17 23:10:54 · 5448 次点击 · 预计阅读时间 5 分钟 · 31分钟之 ...
- android sdk屏幕截图工具
调用android sdk中的工具,在开发板上截图. 使用usb线连接android设备,打开adb调试. 进入目录 sdk/tools/ 运行 traceview.bat 运行 uiautomato ...
- MyBatis-Spring 使用总结
说明:Java-based Config. 不是通过 mybatis 的 SqlSessionFactoryBuilder 来创建 SqlSessionFactory ,而是通过 mybatis-sp ...