【问题标题】:UIScrollView has wrong contentSize with auto layoutUIScrollView 具有自动布局的错误 contentSize
【发布时间】:2014-03-23 12:21:48
【问题描述】:

我在情节提要中有一个类似这样的 iOS 屏幕:

如果我在模拟器中尝试此操作,我无法滚动到第二个 UIView(我使用分页)。我知道发生这种情况是因为 contentSize 的宽度为 320,但我不知道如何使用自动布局来解决它,也不知道如何让它在每个设备位置(横向、纵向)上工作。我只需要在 UIScrollView 中显示一个 UIView。谢谢。

【问题讨论】:

    标签: ios objective-c storyboard autolayout


    【解决方案1】:

    这是可以解决的,应该可以很好地与自动布局一起使用。

    NSDictionary *views = NSDictionaryOfVariableBindings(scrollView, subview1, subview2);
    
    // Constraint the scrollview frame within its parent
    [parentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[scrollView]|" options:0 metrics: 0 views:viewsDictionary]];
    [parentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[scrollView]|" options:0 metrics: 0 views:viewsDictionary]];
    
    // Determine the scrollview's contentSize using its content
    [scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[subview1]|" options:0 metrics: 0 views:viewsDictionary]];
    [scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[subview1][subview2]|" options:0 metrics: 0 views:viewsDictionary]];
    [scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[subview2]|" options:0 metrics: 0 views:viewsDictionary]];
    
    // Set the children width using the outer view
    [parentView addConstraint:[NSLayoutConstraint constraintWithItem:subview1 attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:parentView attribute:NSLayoutAttributeWidth multiplier:1.0 constant:0.0]];
    [parentView addConstraint:[NSLayoutConstraint constraintWithItem:subview2 attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:parentView attribute:NSLayoutAttributeWidth multiplier:1.0 constant:0.0]];
    
    // Set the children height manually
    [parentView addConstraint:[NSLayoutConstraint constraintWithItem:subview1 attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:80.0]];
    [parentView addConstraint:[NSLayoutConstraint constraintWithItem:subview2 attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:80.0]];
    

    如果您遇到问题,请告诉我。这种方式会有适应屏幕方向、屏幕大小、状态栏高度变化等的优势。

    以上示例假设您要将孩子的高度设置为固定高度(80 像素)。要使其垂直填满屏幕,您宁愿执行与宽度相同的操作。

    这还假设scrollviewsubview1subview2 都将其translatesAutoresizingMaskIntoConstraints 属性设置为NO

    它也会在滚动视图中垂直对齐子视图。如果你想这样做,你可以让他们每个人都驻留在他们自己的 container 视图中,如下所示:

    // Set the containers' width & height using the outer view
    [parentView addConstraint:[NSLayoutConstraint constraintWithItem:containerview1 attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:parentView attribute:NSLayoutAttributeWidth multiplier:1.0 constant:0.0]];
    [parentView addConstraint:[NSLayoutConstraint constraintWithItem:containerview2 attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:parentView attribute:NSLayoutAttributeWidth multiplier:1.0 constant:0.0]];
    
    [parentView addConstraint:[NSLayoutConstraint constraintWithItem:containerview1 attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:parentView attribute:NSLayoutAttributeHeight multiplier:1.0 constant:0.0]];
    [parentView addConstraint:[NSLayoutConstraint constraintWithItem:containerview2 attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:parentView attribute:NSLayoutAttributeHeight multiplier:1.0 constant:0.0]];
    
    // Set the children height manually
    [containerview1 addConstraint:[NSLayoutConstraint constraintWithItem:subview1 attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:80.0]];
    [containerview2 addConstraint:[NSLayoutConstraint constraintWithItem:subview2 attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:80.0]];
    
    // Align them vertically
    [containerview1 addConstraint:[NSLayoutConstraint constraintWithItem:subview1 attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:containerview1 attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0.0]];
    [containerview2 addConstraint:[NSLayoutConstraint constraintWithItem:subview2 attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:containerview2 attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0.0]];
    
    // Set the width to equal that of their container
    [containerview1 addConstraint:[NSLayoutConstraint constraintWithItem:subview1 attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:containerview1 attribute:NSLayoutAttributeWidth multiplier:1.0 constant:0.0]];
    [containerview2 addConstraint:[NSLayoutConstraint constraintWithItem:subview2 attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:containerview2 attribute:NSLayoutAttributeWidth multiplier:1.0 constant:0.0]];
    

    【讨论】:

    • 谢谢。是否可以在 Interface Builder 中设置此约束?
    • 我不确定您是否可以在界面构建器中拥有同样的灵活性
    【解决方案2】:

    试试这样的:

    [_scrollView setContentSize:CGSizeMake(640, _scrollView.frame.size.height)];
    

    关于自动布局:有时最好不要使用它们。

    考虑屏幕方向的代码:

    float screenWidth = [UIScreen mainScreen].bounds.size.width;
    [_scrollView setContentSize:CGSizeMake(screenWidth * 2, _scrollView.frame.size.height)];
    

    要捕捉设备旋转的那一刻,您应该在视图控制器中使用这种方法:

    - (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
    {
        // Remove current subviews
    
        for(UIView *subview in _scrollView.subviews)
        {
            [subview removeFromSuperview];
        }
    
        // Fill scroll view with subviews resized for screen size
        // ...
    }
    

    【讨论】:

    • 我试过这样的东西,但这在横向模式下不起作用。
    • 当然它不能在横向上工作,因为屏幕旋转 90 度,宽度和高度会相互替换。只需检查当前的屏幕方向。
    • 其实你甚至不需要检查屏幕方向,它就足以获得屏幕的当前边界结构。我刚刚更新了答案中的代码。
    • 我的意思是内容视图会有问题。您将能够在横向模式下同时看到多个 UIView。
    • 当设备旋转时,您应该从 UIScrollView 中删除所有子视图,并用专门为当前屏幕方向调整大小的其他子视图填充它。
    猜你喜欢
    • 2014-12-29
    • 2016-12-21
    • 1970-01-01
    • 2013-04-12
    • 2013-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多