UIScrollView不滚动


128

我有一个UIScrollView包含许多UIImageView,UILabel等的标签,标签的长度比的长得多UIScrollView,但是当我运行该应用程序时,无法单击并向下滚动...

为什么会这样呢?

谢谢


Answers:


169

展示完整的工作代码片段总是很不错的:

// in viewDidLoad (if using Autolayout check note below):

UIScrollView *myScrollView;
UIView *contentView;
// scrollview won't scroll unless content size explicitly set

[myScrollView addSubview:contentView];//if the contentView is not already inside your scrollview in your xib/StoryBoard doc

myScrollView.contentSize = contentView.frame.size; //sets ScrollView content size

迅捷4.0

let myScrollView
let contentView

// scrollview won't scroll unless content size explicitly set

myScrollView.addSubview(contentView)//if the contentView is not already inside your scrollview in your xib/StoryBoard doc

myScrollView.contentSize = contentView.frame.size //sets ScrollView content size

我还没有找到一种在IB中设置contentSize的方法(从Xcode 5.0开始)

注意:如果使用自动布局,则放置此代码的最佳位置是-(void)viewDidLayoutSubviewsmethod内。


12
别忘了设置myScrollView.delegate = selfALSO,如果仍然无法使用,则下面的答案有很棒的建议(转到xib / StoryBoard并确保已禁用“ AutoLayout”)。专家提示:<UIScrollViewDelegate>如果您希望进行诸如以编程方式滚动UIScrollView之类的操作,则还可以在.h文件中添加该提示。
艾伯特·伦肖

1
@AlbertRenshaw,您应该添加一个答案,这样我可以给您+1了:) AutoLayout是我的问题....让我疯狂了大约4个小时。
logixologist 2014年

2
放入代码viewDidLayoutSubviews使其对我有用。
Amr Lotfy '18年

对我来说,问题在于它不需要滚动,因为所有内容都适合屏幕。
Daniel Springer

122

如果即使正确设置了contentSize也无法滚动视图,请确保在Interface Builder-> File Inspector中取消选中 “ Use AutoLayout”。


164
或者,您可以在viewDidLayoutSubviews:中设置contentSize,它将在自动布局完成后应用。
克里斯·瓦塞利

2
@“ Chris Vasselli”解决了我的问题。GR8 .. :-)
Ayaz

3
克里斯的评论应该是一个单独的答案!
ninjaneer

1
非常感谢Chris Vasselli!启用“自动布局”后,它将在viewDidLoad中不起作用,但在viewDidLayoutSubviews中起作用!
罗曼2014年

1
哇,我以前从未注意到所有这些评论!很高兴我能帮助很多人!我刚刚发布了一个单独的答案,因此希望它会更容易找到。
克里斯·瓦塞利

68

您需要设置contentSize滚动视图的属性才能使其正确滚动。

如果您使用自动布局,你需要设置contentSizeviewDidLayoutSubviews,以便它的自动布局完成后应用。

代码看起来像这样:

-(void)viewDidLayoutSubviews
{
    // The scrollview needs to know the content size for it to work correctly
    self.scrollView.contentSize = CGSizeMake(
        self.scrollContent.frame.size.width,
        self.scrollContent.frame.size.height + 300
    );
}

由于一吨..这工作,因为某种原因,甚至当我设置的值contentSize,以规模contentView,滚动视图和内容查看的大小似乎变得设置为相同。但是,将的高度设置为contentSize大于的高度的值contentView,就可以了。
天行者

viewDidLayoutSubviews在生命周期中可能会多次被调用,因此您冒着增加高度超过预期的风险。
anon_nerd

@anon_nerd只是检查它是否已经被调用,否则就只增加高度
Daniel Springer

45

上面的答案是正确的-要使滚动发生,必须设置内容大小。

如果您使用的是界面生成器,那么一种简便的方法是使用用户定义的运行时属性。例如:

在此处输入图片说明


这对我没有任何帮助。
coolcool1994'2013-4-18

4
糟糕,图片显示{0,0},但是您当然必须输入足够大的数字。。这种方法仅适用于您预先知道内容大小的简单视图。。。(实际上,对于复杂的视图,我还是建议您使用纯代码)。
Jasper Blues

hacky比编程方式要少得多。谢谢!
杰克·斯托弗勒2014年

1
@JakeStoeffler欢迎!:)使用IB时,我希望将所有配置保留在那里(不分散)。但是,当事情变得复杂时(可重用的视图小部件;模型适配器,图层操纵; CAAnimations等),那么我更喜欢完全编程的视图。。。更流利。
贾斯珀·布鲁斯

我尝试了这个,当视图出现时可以工作,但是在方向改变时,上面屏幕上定义的contentSize被忽略,并且我的日志显示contentSize被设置回0,0。任何想法如何解决?
Shoogle 2014年

40

尝试将内容大小调整为大量。我不明白为什么即使内容大小似乎大于控件大小,我的滚动视图也不滚动。我发现,如果内容大小小于所需大小,那么它也不起作用。

self.scrollView.contentSize = CGSizeMake(2000, 2000);

而不是2000,您可以输入自己的大数字。如果可行,则表示您调整大小时内容的大小不够大。

滚动视图不需要委托。


2
天才-一种检查发生情况的简单方法。谢谢一群!
疯狂的黑猩猩

13

确保已将滚动视图的contentSize属性设置为正确的大小(即足够大以容纳所有内容)。


1
我必须以编程方式执行此操作吗?还是可以在IB中做到?
标记

如果您使用的是IB,则可以从那里进行设置-参见下文。。(单独的答案,所以我可以附上照片)。
贾斯珀·布鲁斯


5

在我的情况下,我必须设置delaysContentTouches为true,因为scrollView内部的所有对象都捕获了触摸事件并自行处理,而不是让scrollView自己处理。


我有同样的问题。对我来说,问题是,通过将delaysContentTouches设置为true,您将只能使用苹果铅笔来绘制质量较低的图形。但这是一个
极端的

4

设置in 方法的contentSize属性。像这样UIScrollviewViewDidLayoutSubviews

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    scrollView.contentSize = CGSizeMake(view.frame.size.width, view.frame.size.height)
}

3

为什么滚动视图不滚动的想法是因为您设置的滚动内容大小小于滚动视图的大小,这是错误的。您应将内容大小设置为大于滚动视图的大小,以在滚动时浏览内容。

与缩放相同,您可以设置缩放的最小值和最大值,这将通过缩放动作应用。

欢迎:)


3

上面的一个小附加内容是您的滚动视图可能无法滚动的实际原因,但有时是不经意间这可能是特别是当通过代码而非IB添加滚动视图时的原因,您可能已将子视图添加到了父视图而不是scrollview这将导致子视图不滚动

并确保内容大小设置为大于父视图框架(duhh !!)


3

我第一次尝试就使它起作用。具有自动布局和所有功能,无需其他代码。然后集合视图变成香蕉,在运行时崩溃,我找不到错误所在,因此我删除并重新创建了它(我使用的是Xcode 10 Beta4。感觉就像个错误),然后滚动消失了。不过,“收藏夹”视图再次起作用!

很多小时后..这就是它为我修复的。我有以下布局:

UIView

  • 安全区
  • 滚动视图
    • 内容检视

一切都在约束之中。安全区域由系统自动定义。在最坏的情况下,请删除滚动和内容视图的所有约束,并且没有 IB为您重置/创建它们。手动进行设置即可。

  • 对于滚动视图,我做到了:使尾部/顶部与安全区域对齐。宽度/高度等于安全区域
  • 对于内容视图,我做了以下操作:将尾随/前导/顶部/底部对齐到超级视图(滚动视图)

基本上,概念是让Content视图适合Scrollview,也就是Safe Area。

但是,这样行不通。内容视图错过了高度。我尽了最大的努力,唯一的办法就是创建一个内容视图高度,将控件拖动到内容视图本身。定义了一个固定的高度,该值是从视图控制器的大小(定义为自由格式,比实际显示的长度更长,到包含我的所有子视图)中计算出来的,最后它又可以正常工作了!


不客气!我完全知道您的感受。;-)
Michele Dall'Agata

Thaaaaks,我花了很多时间,这解决了我的问题
Andoni Da Silva,

3

如果收到viewDidLayoutSubviews不存在的消息(IOS8 / Swift),请使用以下内容代替

override func viewDidAppear(animated: Bool)

这为我解决了


2

以前没有提到的东西!

确保您的插座已正确连接到scrollView!它应该有一个实心圆,但是即使您有实心圆,scrollView也可能没有连接-请仔细检查!将鼠标悬停在圆圈上,看看实际的滚动视图是否突出显示!(这是我的情况)

//Connect below well to the scrollView in the storyBoard
@property (weak, nonatomic) IBOutlet UIScrollView *scrollView;

2

如果您遵循了教程,那么很多时候代码是正确的,但是许多初学者不知道的是,scrollView 不会在模拟器中正常滚动。假定仅当您按下鼠标垫同时滚动时才滚动。许多经验丰富的 XCode / Swift / Obj-C用户都习惯这样做,因此他们不知道初学者怎么可能会忽略它。再见 :-)

@IBOutlet weak var scrollView: UIScrollView!
override func viewDidLoad() {
    super.viewDidLoad()
    view.addSubview(scrollView)
    // Do any additional setup after the view
}

override func viewWillLayoutSubviews(){
    super.viewWillLayoutSubviews()
    scrollView.contentSize = CGSize(width: 375, height: 800)
}

只要您按照我上面所说的去做,这段代码就可以正常工作


1

如果没有其他解决方案对您有用,请仔细检查滚动视图实际上是否UIScrollView在Interface Builder中。

在最近几天的某个时候,我的UIScrollView 类型自动更改为a UIView,即使其类别UIScrollView在检查员中说了也是如此。我正在使用Xcode 5.1 (5B130a)

您可以创建一个新的滚动视图并从旧视图复制测量,设置和约束,也可以手动将视图更改UIScrollViewxib文件中的。我进行了比较,发现以下差异:

原版的:

<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" directionalLockEnabled="YES" bounces="NO" pagingEnabled="YES" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Wsk-WB-LMH">
...
</scrollView>

类型自发更改后:

<view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" customClass="UIScrollView" id="qRn-TP-cXd">
...
</view>

所以我用<view>原来的<scrollView>线代替了那条线。

我也换成了视图的结束标记</view></scrollView>

在这种情况下,请确保ID与当前视图保持相同:id =“ qRn-TP-cXd”。

我还必须通过删除应用程序的派生数据来从Xcode的缓存中清除xib:

  • Xcode->Window->Organizer->Projects,选择项目,在“派生数据”行上,单击“删除...”。

或者,如果使用设备:

  • Xcode->Window->Organizer->Device,选择您的设备->应用程序,选择您的应用程序,然后单击(-)

现在清理项目,然后从模拟器/设备中删除该应用程序:

  • Xcode->Product->Clean
  • iOS Simulator/device->press并按住app->click(X)将其删除

然后,您应该能够构建和运行您的应用程序,并再次具有滚动功能。

PS我不必设置滚动视图的内容大小viewDidLayoutSubviews或关闭自动布局,而是YMMV。


1

如果您scrollViewcontainerView某类型的子视图,请确保您scrollView位于的框架或范围内containerView。我containerView.clipsToBounds = NO仍然可以看到scrollView,但是因为scrollView不在containerView它的范围内,所以无法检测到触摸事件。

例如:

containerView.frame = CGRectMake(0, 0, 200, 200);
scrollView.frame = CGRectMake(0, 200, 200, 200);
[containerView addSubview:scrollView];
scrollView.userInteractionEnabled = YES;

您将能够看到scrollView,但不会收到用户交互。


1

viewDidLayoutSubviewsAutolayout中为我工作时添加了以下代码。尝试所有答案后:

- (void)viewDidLayoutSubviews
{
    self.activationScrollView.contentSize = CGSizeMake(IPHONE_SCREEN_WIDTH, 620);

}

//set the height of content size as required

1

添加,UIScrollViewDelegate并将以下代码添加到viewDidAppear为我修复的方法中。

@interface testScrollViewController () <UIScrollViewDelegate>

-(void)viewDidAppear:(BOOL)animated {
    self.scrollView.delegate = self;
    self.scrollView.scrollEnabled = YES;
    self.scrollView.contentSize = CGSizeMake(375, 800);
}

1

我的问题已通过以下方式解决:

  1. 将scrollView上的contentSize设置为较大的高度
  2. 但是我还必须修复scrollView内视图的顶部和/或底部约束,这意味着屏幕上显示了滚动指示器,但内容没有滚动

一旦删除绑定到安全区域和/或超级视图的顶部和/或底部约束,scrollView内部的视图就可以再次滚动,并且不会固定在屏幕底部的顶部!

希望这可以使其他人摆脱这个特定问题的痛苦。


1

另一个有趣的案例:

scrollview.superview.userInteractionEnabled必须为true

我浪费了2个多小时来追逐它,只是为了弄清楚父级是UIImageView,它自然有userInteractionEnabled == false


0

在此线程中提供的答案失败之后,我偶然发现了解决方案。

使用自动布局设置滚动视图有两点不直观:

  1. 在contentview和scrollview之间设置为边距的约束不会影响contentview的大小。他们真的是利润。为了使其正常工作,contentview应该具有固定的大小。
  2. 固定大小的诀窍是,您可以将contentview的宽度设置为与scrollview的父视图相等。只需在左侧的树中选择两个视图,然后添加相等的宽度约束即可。

这是该文章的要旨。有关插图的完整说明,请查看。


@PredragManojlovic如何获得比这更一般的信息?这是我可以使用自动布局使scrollview正常工作的唯一方法。
H. de Jonge

0

我发现存在此AutoLayout问题...如果我只是ViewController使用该类UIView而不是UIScrollView用于该类...则只需添加一个UIScrollView我自己...即可。


0

我在IB中有同样的问题。

将scrollView的开头,结尾,顶部和底部设置为其superView之后。我进行了以下更改,以使containerView可滚动,从而可以正常工作。

若要使scrollView仅在水平方向上滚动,请使用scrollView的centerY = ContainerView的centerY进行约束

并使它可以垂直滚动,使scrollView的centerX = ContainerView的centerX

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.