美文网首页
使用Auto Layout下的UIView上移适配

使用Auto Layout下的UIView上移适配

作者: QihuaZhou | 来源:发表于2016-03-05 22:57 被阅读331次

    背景

    在页面布局中,我们有时候可能会遇到要求用户输入时,弹出的键盘遮挡了用户的输入或者实现,影响了用户的使用体验。
    而一个很普遍的做法就是在如UITextField输入时,把当前的UIView上移合适的距离,不过也会遇到一点小问题,下面可以跟着demo一起来看一下。

    Demo

    1. 新建一个工程,添加一个最简单的UITextField


      在页面下方添加一个UITextField
    2. 在ViewController中添加一个输出口属性@property (weak, nonatomic) IBOutlet UITextField *textFiled;用来标记这个输入框。

      添加textFiled属性
    3. 运行模拟器可以看到,在点击输入框进行输入时,弹出的键盘会覆盖输入框,影响输入。


      键盘弹出影响输入
    4. 我们需要在输入时,View进行上移,留出足够的空间给键盘。下面我们进行相应的实现。
      主要是使用<UITextFieldDelegate>协议的- (void)textFieldDidBeginEditing:(UITextField *)textField方法。在接口方法中实现:一旦开始输入,就上移View。

    5. 我们首先引入<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。

    添加输出口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中操作,这里也涉及了一些用代码修改约束值的方法。
    以上希望能够帮助到大家。感谢阅读!
    欢迎转载,请注明出处。

    相关文章

      网友评论

          本文标题:使用Auto Layout下的UIView上移适配

          本文链接:https://www.haomeiwen.com/subject/qqcakttx.html