UIScrollView不滚动,无论contentSize有多大

11

我已经在接口生成器中创建了一个UIScrollView并添加了子视图,但是我无法使其滚动。我查看了其他类似的问题,但是我已经适当地设置了我的contentSize。实际上,我甚至尝试设置非常大的contentSize也没有任何效果。我错过了什么吗?请注意,UIScrollView是IBOutlet:

@property (strong, nonatomic) IBOutlet UIScrollView *scroll;

这是我的viewDidLoad中的内容:

self.scroll.scrollEnabled = YES;
[self.scroll setContentSize: CGSizeMake(2400,8000)];

以下是Interface Builder的截图:

视图层次结构

滚动视图及其子视图在Interface Builder中的显示

引用插座

以下是运行时的视图,但无论何时尝试水平或垂直滚动,均无法正常工作。

运行时的屏幕


2
你已经将 IBOutlet 连接到故事板了吗? - tia
只返回大小不小于您的ContentSize的内容。 - Shamsudheen TK
我之前尝试过在设置contentSize之前使用self.scroll.frame = [UIScreen mainScreen].bounds;,但没有任何改变。 - golddove
我不确定那是什么。我没有直接使用它,但也许是间接的。我只是在界面构建器中将标签、按钮、文本字段和日期选择器拖到滚动视图中,并使用指南对其中一些进行了对齐。 - golddove
这可能与它嵌套在导航控制器下有关吗?我是从主细节模板开始的,而这个模板位于DetailViewController内部。 - golddove
显示剩余8条评论
5个回答

23

关闭自动布局确实可以解决问题,但那不是最好的解决方案。如果您确实需要自动布局,请使用它;如果不需要,请关闭它。但这并不是正确的解决方法。

UIScrollView在自动布局中与其他视图有所不同。这里是苹果公司关于自动布局的发布说明,我复制了其中有趣的部分(第三个标记点是我加的强调):

以下是一些有关UIScrollView自动布局支持的注释:

  • 通常,自动布局认为视图的顶部、左侧、底部和右侧边缘是可见的边缘。也就是说,如果您将一个视图固定到其父视图的左边缘,那么实际上您是将其固定到父视图边界的最小x值。更改父视图的边界原点不会改变视图的位置。
  • UIScrollView类通过更改其边界的原点来滚动其内容。为使其与自动布局配合使用,滚动视图中的顶部、左侧、底部和右侧边缘现在表示其内容视图的边缘。
  • 滚动视图的子视图的约束条件必须导致填充大小,然后将其解释为滚动视图的内容大小(这不应与用于自动布局的intrinsicContentSize方法混淆)。要使用自动布局调整滚动视图的框架,约束条件必须明确规定滚动视图的宽度和高度,或将滚动视图的边缘绑定到其子树之外的视图。
  • 请注意,您可以通过创建视图与滚动视图子树之外的视图(例如滚动视图的父视图)之间的约束来使滚动视图的子视图看起来浮动(而不是滚动)在其他滚动内容上方。

苹果接着展示了如何正确使用自动布局(Auto Layout)的UIScrollView的例子。

通常,最简单的修复方法是在元素与UIScrollView底部之间创建一个约束。所以在你想要放置在UIScrollView底部的元素中,创建这个底部间隔约束:

enter image description here

再次强调,如果你不想使用自动布局,则需要将其关闭。你可以像平常一样设置contentSize。但你应该理解这是自动布局的预期行为。


1
我仍然困惑为什么之前它没有滚动,但我理解“纯自动布局”方法的工作原理,所以我想使用它而不是简单地禁用自动布局。非常感谢! - golddove
1
我的猜测是之前没有任何限制来表明“内容至少需要这么多!”,编译器忽略了你的setContentSize:调用,因为它只是查看你的约束来确定滚动视图中有多少内容。 - Enrico Susatyo
我曾经遇到过非常类似的问题。我试图创建一个文本字段的滚动视图,这些文本字段会增长并滚动以保持在屏幕上。设置底部约束解决了我的问题! - Elliot Blackburn

2

尝试关闭自动布局功能:

选择ViewController,然后在文件检查器中,在interface builder document部分中,可以看到是否已经选中了Use Autolayout。如果是选中状态,则需要将其取消选中

可以参考UIScrollView和Autolayout获取详细信息。


2
谢谢,这解决了滚动问题,但正如@EnricoSusatyo所说,似乎可以在不禁用自动布局的情况下解决它。 - golddove

1
如果您正在使用自动布局,则将UIScrollView中的所有内容放入另一个UIView中,并将该UIView作为UIScrollView的唯一子视图。然后,您可以使用AutoLayout。
如果靠近UIScrollView滚动方向的末尾出现问题,请将末尾的约束条件更改为最低可能的优先级。

1

尝试使用以下代码自动设置内容大小

首先将您的视图控制器复制并粘贴到viewDidLoad方法中

 [self MHAutoContentSizeForScrollViewWithPadding:10 scrl:YOUR_SCROLLVIEW];

然后复制并粘贴到下面的viewDidLoad方法中

-(void)MHAutoContentSizeForScrollViewWithPadding:(CGFloat)padding scrl:(UIScrollView*)view{
    if ([view isKindOfClass:[UIScrollView class]]) {
        CGRect rect = CGRectZero;
        for(UIView * view in YOUR_SCROLLVIEW.subviews){
            rect = CGRectUnion(rect, view.frame);
        }
        [YOUR_SCROLLVIEW setContentSize:CGSizeMake(rect.size.width, rect.size.height+padding)];
    } else {
        NSLog(@"You can only set the ContentSize for ScrollViews");
    }
}

同时连接YOUR_SCROLLVIEW代理和TextFeild代理 编程愉快!!!


0

我遇到了这个问题,而这个线程中的答案都没有起作用。

我将我的一个子视图在我的UIScrollView中设置了一个顶部约束,使其等于UIViewControllerview.topAnchor。由于它会破坏约束条件,所以我的UIScrollView无法滚动。

一旦我修改了约束条件,并将其设置为UIScrollView.topAnchor,它就按预期工作了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接