UIScrollView 没有滚动

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

为什么会这样?

谢谢

142942 次浏览

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

展示一个完整的工作代码片段总是好的:

// 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 (从 Xcode 5.0开始)中设置 contentSize 的方法。

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

上面的答案是正确的——为了实现滚动,有必要设置内容大小。

如果你使用 Interface Builder,一个简单的方法就是使用用户定义的运行时属性。例如:

enter image description here

尝试将内容大小调整为巨大的数字。我不能理解为什么我的滚动视图不滚动,即使它的内容大小似乎大于控件大小。我发现,如果内容大小小于需要,它也不工作。

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

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

委托对于滚动视图的工作不是必需的。

如果在正确设置 大小之后仍无法滚动视图, 确保你在 Interface Builder 中的 取消检查“使用自动布局”-> 文件检视器。

取消选中“使用自动输出”对我来说很管用。

环境: XCode 5.0.2 故事板 Ios7

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

同样的想法与缩放,您设置的最小和最大值的缩放,将适用于通过缩放行动。

欢迎:)

您需要设置滚动视图的 contentSize属性,以便它能够正确滚动。

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

代码可以是这样的:

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

一个小的补充,以上都是实际原因,为什么你的滚动视图可能不滚动,但有时无意识这可能是原因特别是当滚动视图是通过代码添加,而不是 IB,你可能已经添加了你的子视图的父视图,而不是滚动视图,这导致子视图不滚动

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

如果没有其他解决方案适合你,再次检查你的滚动视图实际上是一个 Interface Builder 的 UIScrollView

在过去几天的某个时候,我的 UIScrollView自发变化的类型变成了 UIView,尽管它的课上说的是 UIScrollView中的检查员。我用的是 Xcode 5.1 (5B130a)

您可以创建一个新的滚动视图并从旧视图中复制度量、设置和约束,或者您可以手动将视图更改为 xib文件中的 UIScrollView。我做了一个比较,发现了以下不同之处:

原文:

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

因此,我用原来的 <scrollView>线替换了 <view>线。

我还将视图的 close 标记 </view>替换为 </scrollView>

确保 id 与当前视图相同,在本例中为: id = “ qRn-TP-cXd”。

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

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

或者如果使用一个设备:

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

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

  • Xcode->Product->Clean
  • IOSSimulator/device->press和举行的 app->click(X)删除它

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

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

一些之前没有提到的事情!

确保您的插座正确连接到 scrollView!它应该有一个填充圆,但即使你有填充圆,scrollView 可能没有连接-所以仔细检查!将鼠标悬停在圆上,看看是否突出显示了实际的 scrollview!(这是我的一个案例)

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

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

if you are getting a message (IOS8 / swift) that viewDidLayoutSubviews does not exist, use the following instead

override func viewDidAppear(animated: Bool)

这东西帮我修好了

如果您的 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,但它不会接收用户交互。

viewDidLayoutSubviews中添加以下代码对我的自动输出很管用:

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


}


//set the height of content size as required

添加 UIScrollViewDelegate并添加以下代码到 viewDidAppear方法为我修复它。

@interface testScrollViewController () <UIScrollViewDelegate>


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

ViewDidLayoutSubviews方法中设置 UIScrollviewcontentSize属性

override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()


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

如果你已经遵循了一个教程,很多时候代码是正确的,但许多初学者不知道的是 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)
}

只要按照我上面说的做,这段代码就可以很好地工作

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

使用自动布局设置 scrollview 有两个不直观的地方:

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

这就是那篇文章的要点。如果想了解完整的解释,包括插图,请查看。

我发现这个自动布局的问题... 如果我只是让 ViewController使用 UIView而不是 UIScrollView的类... 然后只是添加一个 UIScrollView自己... 它的工作。

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

许多小时后,这就是为什么我修好了它。我有以下的布局:

UIView

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

一切都在约束中。安全区域由系统自动定义。在最坏的情况下,移除滚动和内容视图的所有约束,并做 没有有 IB 重置/为您创建它们。手动操作,可以用。

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

基本概念是让内容视图适合滚动视图,这是适合安全区域。

但就此而言,它并没有奏效。内容视图错过了高度。我已经尽力了,唯一能做到这一点的就是 内容视图高度创建控件拖动内容视图。它定义了一个固定的高度,这个值是根据视图控制器的 Size 计算出来的(定义为自由形式,比实际显示的长,包含所有的子视图) ,最后它再次工作了!

我在情报局也遇到过同样的问题。

在将 scrollView 的前导、尾随、顶部和底部设置为其 superView 之后。我进行了以下更改,使容器视图具有可滚动性,这样做是有效的。

为了使 scrollView 只在水平方向上滚动,使用 scrollView 的 centerY = ContainerView 的 centerY 进行约束

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

我的问题通过以下方式得到了解决:

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

一旦我移除了绑定到安全区域和/或超视图的顶部和/或底部约束,scrollView 中的视图可以再次滚动,而不是固定在屏幕底部的顶部!

希望这能让其他人不再因为这个问题痛苦几个小时。

还有一个有趣的例子:

UserInteractionEnable 必须为 true

我花了两个多小时追踪这个,只是为了找出父母 是 UIImageView,它自然拥有 userInteractionEnable = = false

您不必设置滚动视图的内容大小。

技术说明 TN2154

如果有人像我一样犯了同样的错误,我想分享我的案例。

在我的例子中,我错误地在 scrollview 的一个子视图中添加了一个约束,这使得子视图在 topLayoutGuide 中的空间是固定的,因此它的位置不能改变,所以 scrollview 不能滚动。

简单的编程方式

把它包起来

创建一个 UIScrollView

private lazy var scrollView: UIScrollView = {
let scrollView = UIScrollView()
scrollView.translatesAutoresizingMaskIntoConstraints = false


return scrollView
}()

使用单个子视图保存所有内容子视图

private lazy var contentView: UIView = {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false


return view
}()

添加您的观点

contentView.addSubview(firstSubView)
contentView.addSubview(lastSubView)
scrollView.addSubview(contentView)
view.addSubview(scrollView)

通常,您只希望内容向一个方向滚动。在大多数情况下垂直滚动。因此,将内容视图的宽度设置为滚动视图的宽度。

NSLayoutConstraint.activate([
contentView.widthAnchor.constraint(equalTo: scrollView.widthAnchor)

将单个内容视图的四个约束(顶部、底部、左侧、右侧)附加到滚动视图。

    contentView.topAnchor.constraint(equalTo: scrollView.topAnchor),
contentView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor),
contentView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor),
contentView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor),

请确保您有 附加到内容视图的所有四个方面的约束,以便它将扩展到您的内容的大小。

// After Adding your subviews to the contentView make sure you've those two constraints set:


firstSubView.topAnchor.constraint(equalTo: contentView.topAnchor),
.
.
.
lastSubView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
])

参考资料: 在 iOS 中使用 UIScrollView 实现自动布局