UIScrollView不滚动

问题描述 投票:121回答:24

我有一个UIScrollView,其中包含许多UIImageViews,UILabels等...标签比UIScrollView长得多,但是当我运行应用程序时,我无法点击并向下滚动...

为什么会这样?

谢谢

ios iphone ipad uiscrollview
24个回答
162
投票

显示完整的工作代码片段总是很好:

// 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

Swift 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开始)。

注意:如果您使用的是Autolayout,那么放置此代码的最佳位置是在-(void)viewDidLayoutSubviews方法中。


3
投票

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

与缩放相同的想法,您设置缩放的最小值和最大值,这将通过缩放操作应用。

欢迎:)


3
投票

一个小的补充,以上都是滚动视图可能不滚动的实际原因,但有时候这可能是盲目地通过代码而不是IB添加scrollview的原因,您可能已将子视图添加到父视图而不是scrollview导致子视图不滚动

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


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)
}

只要您执行我上面所说的操作,此代码就可以正常工作


2
投票

我第一次尝试就开始工作了。使用自动布局和一切,没有额外的代码。然后一个集合视图变成了香蕉,在运行时崩溃,我找不到有什么问题,所以我删除并重新创建它(我使用的是Xcode 10 Beta 4.感觉就像一个bug)然后滚动就消失了。但是,Collection视图再次起作用!

很多个小时后......这就是为我解决的问题。我有以下布局:

的UIView

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

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

  • 对于滚动视图,我做了:将尾随/顶部对齐到安全区域。等宽/高度到安全区域。
  • 对于内容视图,我做了:将尾随/前导/上/下对齐到Superview(滚动视图)

基本上这个概念是让内容视图适合Scrollview,它适合安全区域。

但就这样它没有用。内容视图错过了高度。我尽我所能,唯一一个做技巧的是内容视图高度创建控件 - 拖动内容视图..自己。这定义了一个固定的高度,该值是根据视图控制器的大小(定义为自由形式,比实际显示更长,包含所有我的子视图)计算出来的,最后再次工作!


1
投票

如果其他解决方案都不适合您,请仔细检查您的滚动视图实际上是Interface Builder中的UIScrollView

在最近几天的某个时刻,我的UIScrollView自发地改变了类型为UIView,尽管它的班级在检查员中说UIScrollView。我正在使用Xcode 5.1 (5B130a)

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

原版的:

<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)将其删除

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

附:我没有必要在viewDidLayoutSubviews中设置滚动视图的内容大小或关闭自动布局,但是YMMV。


1
投票

如果你的scrollView是某种类型的containerView的子视图,那么请确保你的scrollViewcontainerView的框架或范围内。我有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
投票

viewDidLayoutSubviews中添加以下代码为Autolayout工作。在尝试了所有答案之后:

- (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);
}

119
投票

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


1
投票

我的问题解决了:

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

一旦我删除了绑定到安全区域和/或superview的顶部和/或底部约束,scrollView中的视图可以再次滚动,并且不会保持固定在屏幕底部的顶部!

希望这可以阻止其他人因为这个特殊问题而痛苦不堪。


0
投票

在这个帖子中提供的答案失败后,我偶然发现this article的解决方案。

使用autolayout设置scrollview有两个不直观的事情:

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

这是那篇文章的要点。有关完整说明(包括插图),请查看。


0
投票

我发现有这个AutoLayout问题...如果我只是让ViewController使用UIView而不是UIScrollView为班级...然后自己添加一个UIScrollView ...它的工作原理。


0
投票

我在IB中遇到了同样的问题。

将scrollView的前导,尾随,顶部和底部设置为superView后。我进行了以下更改,以使containerView可滚动,这是有效的。

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

并使其垂直可滚动使scrollView的centerX = ContainerView的centerX


0
投票

另一个有趣的案例:

scrollview.superview.userInteractionEnabled必须为true

我浪费了2 + hrs追逐这只是为了弄清楚父是UIImageView,当然,有userInteractionEnabled == false


66
投票

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

如果您正在使用autolayout,则需要在contentSize中设置viewDidLayoutSubviews,以便在自动布局完成后应用它。

代码可能如下所示:

-(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
    );
}

45
投票

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

如果您正在使用界面构建器,那么使用用户定义的运行时属性可以采用一种简洁的方法。例如:


38
投票

尝试将内容大小调整为大量。我无法理解为什么我的滚动视图即使其内容大小似乎大于控件大小也不会滚动。我发现如果内容大小小于需要,它也不起作用。

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

而不是2000你可以把你自己的大数字。如果它有效,则意味着当您调整大小时,您的内容大小不够大。

滚动视图无需委托即可工作。


13
投票

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


7
投票

取消选中“使用Autolayout”为我做了诀窍。

环境:xCode 5.0.2故事板ios7


4
投票

在我的情况下,我必须将delaysContentTouches设置为true,因为scrollView中的对象都捕获触摸事件并处理自己,而不是让scrollView本身处理它。


4
投票

contentSize方法中设置UIScrollviewViewDidLayoutSubviews属性。像这样的东西

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    scrollView.contentSize = CGSizeMake(view.frame.size.width, view.frame.size.height)
}
© www.soinside.com 2019 - 2024. All rights reserved.