【问题标题】:Does UIScrollview works correct with UIStatusbar?UIScrollview 是否适用于 UIStatusbar?
【发布时间】:2015-07-13 15:44:57
【问题描述】:

我的问题与 UIScrollview 有关。让我们描述一下,

我有一个带有滚动视图的注册屏幕,最初滚动未启用。当键盘出现时,我将启用滚动视图,当键盘再次隐藏时,我将禁用滚动。我的滚动视图的宽度和高度与其默认视图相同,我在容器中应用了水平和垂直中心,并且顶部、底部、前缘和后缘为零(即它等于默认视图)。我有一个注册按钮,它导航到注册屏幕,并应用了底部约束(底部空间约束 = 0),我也在使用键盘通知来显示和隐藏。

实际问题: 当点击文本字段键盘出现时,滚动视图滚动,当我关闭键盘时,滚动视图下降,但这次注册按钮会向上移动一点(就像底部空间有 20 点限制)。

第一次它的类似滚动视图在状态栏之后启动,但是当键盘出现并隐藏它的类似滚动视图时,它会呈现包括状态栏在内的视图。

我需要在 IB 中添加与Top/Bottom Layout Guide 相关的任何约束吗? 还是我需要添加与viewDidLoad相关的任何约束

键盘通知代码。

-(void)keyboardWillShow:(NSNotification *)notification {
    [self.navigationController.navigationBar setBackgroundImage:nil
                                                  forBarMetrics:UIBarMetricsDefault];
    self.navigationController.navigationBar.shadowImage = nil;
    self.ContentScrollView.scrollEnabled=YES;
    NSDictionary *userInfo = [notification userInfo];

    CGRect keyboardFrameInWindow;
    [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&keyboardFrameInWindow];

    // the keyboard frame is specified in window-level coordinates. this calculates the frame as if it were a subview of our view, making it a sibling of the scroll view
    CGRect keyboardFrameInView = [self.ContentScrollView convertRect:keyboardFrameInWindow fromView:nil];

    CGRect scrollViewKeyboardIntersection = CGRectIntersection(self.ContentScrollView.frame, keyboardFrameInView);
    UIEdgeInsets newContentInsets = UIEdgeInsetsMake(0, 0, scrollViewKeyboardIntersection.size.height, 0);

    // this is an old animation method, but the only one that retains compatibility between parameters (duration, curve) and the values contained in the userInfo-Dictionary.
    [UIView animateWithDuration:[[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue] delay:0.0 options:[[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue] animations:^{
        self.ContentScrollView.contentInset = newContentInsets;
        self.ContentScrollView.scrollIndicatorInsets = newContentInsets;

        /*
         * Depending on visual layout, _activeField should either be the input field (UITextField,..) or another element
         * that should be visible, e.g. a purchase button below an amount text field
         * it makes sense to set _activeField in delegates like -textFieldShouldBeginEditing: if you have multiple input fields
         */
        if (_activeField) {
            CGRect controlFrameInScrollView = [self.ContentScrollView convertRect:_activeField.bounds fromView:_activeField]; // if the control is a deep in the hierarchy below the scroll view, this will calculate the frame as if it were a direct subview
            controlFrameInScrollView = CGRectInset(controlFrameInScrollView, 0, 0); // replace 10 with any nice visual offset between control and keyboard or control and top of the scroll view.

            CGFloat controlVisualOffsetToTopOfScrollview = (controlFrameInScrollView.origin.y - self.ContentScrollView.contentOffset.y)+10;
            CGFloat controlVisualBottom = controlVisualOffsetToTopOfScrollview + controlFrameInScrollView.size.height;

            // this is the visible part of the scroll view that is not hidden by the keyboard
            CGFloat scrollViewVisibleHeight = self.ContentScrollView.frame.size.height - scrollViewKeyboardIntersection.size.height;

            if (controlVisualBottom > scrollViewVisibleHeight) { // check if the keyboard will hide the control in question
                // scroll up until the control is in place
                CGPoint newContentOffset = self.ContentScrollView.contentOffset;
                newContentOffset.y += (controlVisualBottom - scrollViewVisibleHeight);

                // make sure we don't set an impossible offset caused by the "nice visual offset"
                // if a control is at the bottom of the scroll view, it will end up just above the keyboard to eliminate scrolling inconsistencies
                CGFloat maxScrollViewHeight = MAX(self.ContentScrollView.frame.size.height, self.ContentScrollView.contentSize.height);
                newContentOffset.y = MIN(newContentOffset.y, maxScrollViewHeight - scrollViewVisibleHeight);
                [self.ContentScrollView setContentOffset:newContentOffset animated:NO]; // animated:NO because we have created our own animation context around this code
            } else if (controlFrameInScrollView.origin.y < self.ContentScrollView.contentOffset.y) {
                // if the control is not fully visible, make it so (useful if the user taps on a partially visible input field
                CGPoint newContentOffset = self.ContentScrollView.contentOffset;
                newContentOffset.y = controlFrameInScrollView.origin.y;

                [self.ContentScrollView setContentOffset:newContentOffset animated:NO]; // animated:NO because we have created our own animation context around this code
            }
        }

    } completion:NULL];
}


- (void)keyboardWillHide:(NSNotification *)notification {

    NSDictionary *userInfo = [notification userInfo];
    [UIView animateWithDuration:[[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey]doubleValue ] delay:0.01 options:[[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey]intValue] animations:^{
        UIEdgeInsets contentInsets = UIEdgeInsetsZero;
        self.ContentScrollView.contentInset = contentInsets;
        self.ContentScrollView.scrollIndicatorInsets = contentInsets;

        CGPoint scrollPoint;
            self.ContentScrollView.scrollEnabled=NO;
            scrollPoint = CGPointMake(0.0, 0.0);

        [self.ContentScrollView setContentOffset:scrollPoint animated:YES];

    } completion:^(BOOL finished){
        __weak typeof(self) weakSelf=self;
        [weakSelf.navigationController.navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
        weakSelf.navigationController.navigationBar.shadowImage = [UIImage new];
    }];

}

图片

如果进一步需要,我将发送键盘通知前后的屏幕截图。

谢谢。

【问题讨论】:

  • self. automaticallyAdjustsScrollViewInsets=NO; 写入viewDidLoad 并尝试
  • 谢谢,这是正确的,正如我所需要的。
  • 欢迎。我已经回答了这个问题。您可以接受这一点,以便其他用户可以从中获得帮助。

标签: ios objective-c uiscrollview interface-builder uistatusbar


【解决方案1】:

来自Documentation

一个布尔值,指示视图控制器是否应该 自动调整其滚动视图插图。

声明

@property(nonatomic, assign) BOOL automaticallyAdjustsScrollViewInsets

讨论

默认值为YES,允许视图控制器调整它的 滚动视图插入以响应屏幕区域所消耗的 状态栏、导航栏和工具栏或标签栏。如果你设置为 NO 想要自己管理滚动视图插图调整,例如何时 视图层次结构中有多个滚动视图。

viewDidLoad中写入self. automaticallyAdjustsScrollViewInsets=NO;并尝试

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多