【问题标题】:iOS AutoLayout with scrollview and keyboard带有滚动视图和键盘的 iOS 自动布局
【发布时间】:2013-11-13 05:31:41
【问题描述】:

我的故事板上有一个视图来显示用户登录表单,所以它看起来像这样:主视图->滚动视图->内容视图->顶部的两个文本字段和登录按钮和一个注册按钮视图的底部。我使用自动布局,底部按钮有底部空间限制。当我点击文本字段并出现键盘时,我想滚动视图以将大小更改为可见矩形,但内容大小应保持向下滚动到注册按钮,但当滚动视图的大小发生变化时,按钮会向上移动。我怎么能做我想做的事?

当键盘出现时我使用这个代码:

- (void)keyboardWillShow:(NSNotification *)aNotification
{
    NSDictionary *info = [aNotification userInfo];
    NSValue *kbFrame = [info objectForKey:UIKeyboardFrameEndUserInfoKey];
    NSTimeInterval animationDuration = [[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
    CGRect keyboardFrame = [kbFrame CGRectValue];

    CGSize s = self.scrollView.contentSize;
    CGFloat height = keyboardFrame.size.height;
    self.scrollViewBottomLayoutConstraint.constant = height;

    [UIView animateWithDuration:animationDuration animations:^{
        [self.view layoutIfNeeded];
        [self.scrollView setContentSize:s];
    }];
}

【问题讨论】:

    标签: ios uiscrollview autolayout


    【解决方案1】:

    尝试不考虑内容大小,而是调整滚动视图的 contentInset 属性。这样你就不必乱用约束了。

    - (void)keyboardUp:(NSNotification *)notification
    {
        NSDictionary *info = [notification userInfo];
        CGRect keyboardRect = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
        keyboardRect = [self.view convertRect:keyboardRect fromView:nil];
    
        UIEdgeInsets contentInset = self.scrollView.contentInset;
        contentInset.bottom = keyboardRect.size.height;
        self.scrollView.contentInset = contentInset;
    }
    

    【讨论】:

    • 漂亮而简单,但一个问题是滚动视图栏不会调整到滚动/表格/集合视图的可见部分。
    • 谢谢。你节省了我的时间。
    【解决方案2】:

    我发现最好的方法是像这样覆盖 NSLayoutConstraint:

    @implementation NHKeyboardLayoutConstraint
    
    - (void) dealloc {
        [[NSNotificationCenter defaultCenter] removeObserver:self];
    }
    
    - (void) awakeFromNib {
        [super awakeFromNib];
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(keyboardWillChangeFrame:)
                                                     name:UIKeyboardWillChangeFrameNotification
                                                   object:nil];
    }
    
    - (void)keyboardWillChangeFrame:(NSNotification *)notification {
    
        CGRect endKBRect = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
    
        CGFloat animationDuration = [notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue];
        CGRect frame = [UIApplication sharedApplication].keyWindow.bounds;
    
        self.constant = frame.size.height - endKBRect.origin.y;
    
    
        [UIView animateWithDuration:animationDuration animations:^{
            [[UIApplication sharedApplication].keyWindow layoutIfNeeded];
        }];
    }
    
    
    @end
    

    然后在您的 xib 中将违规约束的类类型更改为此类。

    【讨论】:

    • 谢谢你!我花了几天时间尝试使用 Bilobatum 描述的常用解决方案,并且我之前成功使用过。现在我有一个相当复杂的布局,必须限制在底部,然后旧的“技巧”就不起作用了。现在我只是用这个类替换了这个约束,它起作用了!我做了一个小补充:float offset = 0; if (endKBRect.origin.y < frame.size.height) offset = [UIApplication sharedApplication].keyWindow.safeAreaInsets.bottom; self.constant = frame.size.height - endKBRect.origin.y - offset; 支持无home键手机。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-11
    • 1970-01-01
    • 1970-01-01
    • 2016-04-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多