背景
在页面布局中,我们有时候可能会遇到要求用户输入时,弹出的键盘遮挡了用户的输入或者实现,影响了用户的使用体验。
而一个很普遍的做法就是在如UITextField输入时,把当前的UIView上移合适的距离,不过也会遇到一点小问题,下面可以跟着demo一起来看一下。
Demo
-
新建一个工程,添加一个最简单的UITextField
-
在ViewController中添加一个输出口属性
@property (weak, nonatomic) IBOutlet UITextField *textFiled;
用来标记这个输入框。
-
运行模拟器可以看到,在点击输入框进行输入时,弹出的键盘会覆盖输入框,影响输入。
我们需要在输入时,View进行上移,留出足够的空间给键盘。下面我们进行相应的实现。
主要是使用<UITextFieldDelegate>协议的- (void)textFieldDidBeginEditing:(UITextField *)textField
方法。在接口方法中实现:一旦开始输入,就上移View。我们首先引入<UITextFieldDelegate>协议,并设置本ViewController为delegate。增加如下代码:
@interface ViewController ()<UITextFieldDelegate>
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.textFiled.delegate = self;
}
6.在协议方法中完成上移功能,代码如下:
#pragma mark - UITextFieldDelegate 输入时上移UIView
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
//UIView上移所需的差值:textFiled起点y + textFiled高度height + 键盘高度216点 + 间隔高度61点 - view的高度height
CGFloat offset = (self.textFiled.frame.origin.y + self.textFiled.frame.size.height + 216 + 61) - self.view.frame.size.height;
[UIView animateWithDuration:0.3 animations:^{
CGRect frame = self.view.frame;
frame.origin.y -= offset;//上移UIView
self.view.frame = frame;
}];
}
7.再次运行可以看到输入框移到了键盘上方,现在不影响输入了。
8.一般来说这样似乎满足要求了,但是我们在进行页面布局时,没用添加约束,而在工程中几乎肯定是要添加各种约束来确保布局的准确性的,而一旦添加了约束,大家就可以发现,上述的方法会失效。
下面我们分别在X和Y方向各添加一个约束,使输入框的位置得以确定。
两个约束很简单,分别是左侧页边距,与顶部导航栏的距离。
9.下面再次运行,可以看到键盘又一次覆盖了输入框。
由于给textField添加了约束,而约束是相对于它的SuperView即这个最基本View,因此虽然View的frame移动了,但是textField相对于View的位置没有改变,而是被约束牢牢固定住了。
那么,怎样才能使得textField再次上移呢,这里就要用到NSLayoutConstraint来改变约束的值了。这里我们需要修改两个约束中,相对于导航栏距离的约束,如图:
10.修改方法很简单,选择这个属性,开启Assistant Editor,向ViewCOntroller添加一个输出口,署名topMargin。
11.之后在textField协议方法中,我们不再修改View的frame,而是修改这个约束的值。代码如下:
#pragma mark - UITextFieldDelegate 输入时上移UIView
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
//UIView上移所需的差值:textFiled起点y + textFiled高度height + 键盘高度216点 + 间隔高度61点 - view的高度height
CGFloat offset = (self.textFiled.frame.origin.y + self.textFiled.frame.size.height + 216 +61) - self.view.frame.size.height;
[UIView animateWithDuration:0.3 animations:^{
// CGRect frame = self.view.frame;
// frame.origin.y -= offset;//上移UIView
// self.view.frame = frame;
self.topMargin.constant -= offset;
//提前载入layout,形成动画效果
[self.view layoutIfNeeded];
}];
}
原先的三行代码注释掉,改写两行新代码。对于一个约束,我们可以这样描述:firstItem.attributeA = secondItem.attributeB * multipler + constant
,我们这里只要修改 constant
的值即可。
其中的[self.view layoutIfNeeded]
是预载入layout,并能形成动画过渡效果。不加这行代码也没有关系,只是画面切换会比较僵硬。
12.运行,发现键盘不再遮挡输入框了,大功告成!
总结
这次我们简单讲述了一个界面适配,键盘弹出,UIView上移的问题。并在有约束的情况下,进行了修正,使用AutoLayout是当下趋势,但我们一般都直接在IB中操作,这里也涉及了一些用代码修改约束值的方法。
以上希望能够帮助到大家。感谢阅读!
欢迎转载,请注明出处。