使用键盘和自动布局管理视图

时间:2016-04-20 10:11:08

标签: ios objective-c keyboard autolayout

我有以下视图层次结构。在UITextfields中查看 - >容器 - > 2 button和1 containerView。容器位于屏幕的中心。我想要做的是在键盘出现时向上移动容器,键盘后面有UITextfield,键盘消失后移回中心。这是相同的屏幕截图。

enter image description here

我需要更改哪些约束,还是需要在代码中添加约束?

5 个答案:

答案 0 :(得分:2)

在键盘显示时获取容器的框架并更新新的框架尺寸。 'setTranslatesAutoresizingMaskIntoConstraints'是更新视图框架时的正确解决方案。它对我有用

enter image description here

 @implementation ViewController
{
CGRect defaultFrame;
}

- (void)viewDidLoad {
[super viewDidLoad];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}
#pragma mark Notifications

- (void)keyboardWillShow:(NSNotification *)notification {
CGSize keyboardSize = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
defaultFrame = self.ContentView.frame;

[self.ContentView setTranslatesAutoresizingMaskIntoConstraints:YES];
[self.ContentView layoutIfNeeded];

CGRect contentInsets = CGRectMake(defaultFrame.origin.x, (keyboardSize.height), defaultFrame.size.width, defaultFrame.size.height);
[UIView animateWithDuration:0.5f
                 animations:^{
                     self.ContentView.frame = contentInsets;

                 }
                 completion:^(BOOL finished){

                 }
 ];

self.ContentView.frame = contentInsets;

}

- (void)keyboardWillHide:(NSNotification *)notification {
[self.ContentView setTranslatesAutoresizingMaskIntoConstraints:NO];
[UIView animateWithDuration:0.5f
                 animations:^{
                     self.ContentView.frame = defaultFrame;
                 }
                 completion:^(BOOL finished){

                 }
 ];

}

答案 1 :(得分:0)

据我所知,当UITextField成为第一个响应者时(即将键盘添加到视图中),您试图移动整个视图?如果是这种情况,我会在UITextField委托方法中添加代码:

#define VIEW_TAG 12345
#define kKeyboardOffsetY 80.0f

- (void)textFieldDidBeginEditing:(UITextField *)textField {
    // get a reference to the view you want to move when editing begins
    // which can be done by setting the tag of the container view to VIEW_TAG
    UIView *containerView = (UIView *)[self.view viewWithTag:VIEW_TAG];
    [UIView animateWithDuration:0.3 animations:^{
        containerView.frame = CGRectMake(0.0f, -kKeyboardOffsetY, containerView.frame.size.width, containerView.frame.size.height);
    }];
}

- (void)textFieldDidEndEditing:(UITextField *)textField {
    UIView *containerView = (UIView *)[self.view viewWithTag:VIEW_TAG];
    [UIView animateWithDuration:0.3 animations:^{
        containerView.frame = CGRectMake(0.0f, self.view.frame.origin.y, containerView.frame.size.width, containerView.frame.size.height);
    }];
}

答案 2 :(得分:0)

通过ctrl +从respactive约束拖动来获取底部约束的IBOutlet或容器视图的顶部约束。

如果底部约束然后在键盘出现时增加约束常数等于键盘高度,当键盘消失时减少相同值。

如果使用顶部约束,则在键盘出现时减小等于键盘高度的常量,并在键盘消失时增加相同值。

例如,

 topConstraint.constant = topConstraint.constant + keyboardHeight;

更新:

根据你的约束,你应该采取垂直中心或中心x的出口,你应该做类似的事情,

 self.verticallyCenter.constant =  self.horizontalyCenter.constant - 100 //here 100 is keyboardheight for example and do it in viewdidload

这样,您的容器视图最多可达100像素。

当辞职键盘时,你可以向其添加100常量以获得初始位置。 希望这会有所帮助:)

答案 3 :(得分:0)

在.h文件中添加UITextFieldDelegate 并尝试以下代码,它一定会帮助你

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
    if (textField == username)
    {
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardDidShowNotification object:nil];

    }
    if (textField == password)
    {
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardDidShowNotification object:nil];

    }

    return YES;
}
- (void)textFieldDidBeginEditing:(UITextField *)textField
{

}
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField
{
    if (textField == username)
    {
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardDidHideNotification object:nil];
    }

    if (textField == password)
    {
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardDidShowNotification object:nil];

    }
    return YES;
}


- (void)keyboardWillShow:(NSNotification *)notification
{
    CGSize keyboardSize = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;

    float newVerticalPosition = -keyboardSize.height + 100;

    [self moveFrameToVerticalPosition:newVerticalPosition forDuration:0.3f];
}


- (void)keyboardWillHide:(NSNotification *)notification
{
    CGFloat  kNavBarHeight =  self.navigationController.navigationBar.frame.size.height;
    [self moveFrameToVerticalPosition:kNavBarHeight forDuration:0.3f];
}


- (void)moveFrameToVerticalPosition:(float)position forDuration:(float)duration
{
    CGRect frame = self.view.frame;
    frame.origin.y = position;

    [UIView animateWithDuration:duration animations:^{
        self.view.frame = frame;
    }];
}

答案 4 :(得分:0)

似乎你已经给出了正确的约束你现在需要做的就是制作一个中心y约束的出口,并在键盘显示/隐藏事件上改变它,你可以用keyboardDidShow / keyboardWillShow和keyboardDidHide来获取它/ keyboardWillHide通知。那说你也可以为这些变化添加很酷的动画效果。如果您需要示例,请试着告诉我。

修改

将viewcontroller添加为两个通知的观察者:

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(keyboardWasShown:)
                                             name:UIKeyboardDidShowNotification
                                           object:nil];

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(keyboardDidHide:)
                                             name:UIKeyboardDidHideNotification
                                           object:nil];

现在假设约束的名称为" constraintForTopSpace",然后为通知添加两种方法:

- (void)keyboardWasShown:(NSNotification *)notification {
    // Get the size of the keyboard.
    CGSize keyboardSize = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;

    //Given size may not account for screen rotation
    int height = MIN(keyboardSize.height,keyboardSize.width);

    // Here you can set your constraint's constant to lift your container up.
    [UIView animateWithDuration:0.5 animations:^{
        [constraintForTopSpace setConstant:constraintForTopSpace.constant - height];
        [self.view layoutIfNeeded];
    }];
}

- (void)keyboardDidHide:(NSNotification *)notification {
    CGSize keyboardSize = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;

    int height = MIN(keyboardSize.height,keyboardSize.width);

    // Here you can set your constraint's constant to move your container down.
    [UIView animateWithDuration:0.5 animations:^{
        [constraintForTopSpace setConstant:constraintForTopSpace.constant + height];
        [self.view layoutIfNeeded];
    }];
}

您还可以使用UIKeyboardWillShowNotification / UIKeyboardWillHideNotification通知,这些通知会在键盘出现在屏幕上之前触发,符合您的要求。

此处添加动画将提供流畅的外观和感觉。 ;)