ChatGPT解决这个技术问题 Extra ChatGPT

UIScrollView 不滚动

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

为什么会这样?

谢谢

新 3/26/2013 我偶然发现了一种无需代码(设置 contentSize)的更简单方法stackoverflow.com/a/15649607/1705353

R
Rohit Pathak

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

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

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


不要忘记设置 myScrollView.delegate = self ALSO,如果这仍然不起作用,下面的答案有很好的建议(转到您的 xib/StoryBoard 并确保禁用“自动布局”)。专业提示:如果您希望以编程方式滚动 UIScrollView 等操作,还可以在 .h 文件中包含 <UIScrollViewDelegate>
@AlbertRenshaw,您应该添加一个答案,这样我就可以给您+1 :) AutoLayout 是我的问题....让我发疯了大约 4 个小时。
将代码放入 viewDidLayoutSubviews 使它对我有用。
对我来说,问题是它不需要滚动,因为一切都适合屏幕。
u
user1539652

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


或者,您可以在 viewDidLayoutSubviews: 中设置 contentSize,它将在自动布局完成后应用。
@“Chris Vasselli”解决了我的问题.. GR8..:-)
克里斯的评论应该是一个单独的答案!
非常感谢克里斯瓦塞利!启用自动布局后,它在 viewDidLoad 中不起作用,但在 viewDidLayoutSubviews 中起作用!
哇,我以前从未注意到所有这些评论!很高兴能帮到你们这么多人!我刚刚发布了一个单独的答案,所以希望它会更容易找到。
J
Jose Llausas

您需要设置滚动视图的 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
    );
}

非常感谢.. 这很有效,因为出于某种原因,即使我将 contentSize 的值设置为 contentView 的大小,scrollView 和 contentView 的大小似乎也设置为相同。但是将 contentSize 的高度设置为大于 contentView 的高度的值,它起作用了。
viewDidLayoutSubviews 在生命周期中可能会被多次调用,因此您冒着增加高度超出预期的风险。
@anon_nerd 只需检查它是否已被调用,如果没有则仅添加高度
J
Jasper Blues

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

如果您正在使用界面构建器,那么一种巧妙的方法是使用用户定义的运行时属性。例如:

https://i.stack.imgur.com/EFkqw.png


这对我没有任何作用。
糟糕,图片显示 {0, 0},但您当然必须输入足够大的数字。 . .这种方法仅适用于您预先知道内容大小的简单视图。 . . (事实上,对于复杂的视图,无论如何我推荐纯代码)。
比以编程方式执行它要简单得多。谢谢!
@JakeStoeffler 欢迎您! :) 使用 IB 时,我喜欢将所有配置保留在那里(不分散)。但是当事情变得复杂时(可重用的视图小部件;模型适配器,层操作;CAAnimations 等),我更喜欢完全编程的视图。 . .更流畅。
我试过这个,当视图出现时工作,但是在方向改变时,上面屏幕上定义的 contentSize 被忽略,我的日志说 contentSize 被设置回 0,0。知道如何解决吗?
A
Alex Zavatone

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

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

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

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


天才 - 一种检查发生了什么的简单方法。非常感谢!
B
Ben Gottlieb

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


我必须以编程方式执行此操作吗?或者我可以在IB做吗?
如果您使用的是 IB,则可以从那里进行设置 - 见下文。 . (单独的答案,所以我可以包括图片)。
G
Gaurav Kumkar

取消选中“使用自动布局”对我有用。

环境:xCode 5.0.2 Storyboards ios7


d
devios1

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


我有同样的问题。对我来说,问题是通过将 delaysContentTouches 设置为 true,您将使用苹果铅笔以较低质量的绘图结束。但这是一个边缘案例:)在大多数情况下它解决了问题
K
Kuldeep

ViewDidLayoutSubviews 方法中设置 UIScrollviewcontentSize 属性。像这样的东西

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

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

A
Atef

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

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

欢迎 :)


A
Abhinav Singh

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

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


M
Michele Dall'Agata

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

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

界面视图

安全区

滚动视图 内容视图

内容视图

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

对于滚动视图,我做了:将尾随/顶部对齐到安全区域。与安全区域相等的宽度/高度。

对于内容视图,我做了:将尾随/前导/顶部/底部与 Superview 对齐(滚动视图)

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

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


不客气!我完全知道你的感受.. ;-)
Thaaaaks,我花了很多时间,这解决了我的问题
K
Kuldeep

如果您收到 viewDidLayoutSubviews 不存在的消息(IOS8 / swift),请改用以下内容

override func viewDidAppear(animated: Bool)

这为我解决了


H
Henry Heleine

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

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

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

希望这可以阻止其他人因这个特定问题而遭受数小时的痛苦。


这次真是万分感谢!!我正在使用水平滚动视图,并且我对第一个子视图的前导约束被约束到超级视图的前导锚点 - 而不是滚动视图的前导锚点。
A
Anton Tropashko

另一个有趣的案例:

scrollview.superview.userInteractionEnabled 必须为 true

我浪费了 2 个小时以上的时间来追查这个只是为了弄清楚父级是 UIImageView,它自然地具有 userInteractionEnabled == false


一样的情况!你是救生员。非常感谢!
哟。即使有这样的情况,也比编程机器人更容易紧张
对的说。但是,就我而言,我在基于 .xib 的自定义 UIView 子类中有一个 UIScrollview,它添加在 UIImageView 之上,而 UIImageView 又是 UIViewController 视图的子视图,所以我几乎不会猜到它与UIImageView。 :)
c
coolcool1994

之前没有提到的东西!

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

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

f
flo527

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

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


K
Kuldeep

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

@interface testScrollViewController () <UIScrollViewDelegate>

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

D
Dharmesh Dhorajiya

如果其他解决方案都不适合您,请仔细检查您的滚动视图是否确实是 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> 行。

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

请务必保持 id 与当前视图相同,在本例中为:id="qRn-TP-cXd"。

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

Xcode->Window->Organizer->Projects,选择你的项目,在 Derived Data 行,点击 Delete...

或者,如果使用设备:

Xcode->Window->Organizer->Device,选择你的设备->Applications,选择你的应用,点击(-)

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

Xcode->产品->清理

iOS模拟器/设备->按住app->点击(X)将其移除

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

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


C
Chase Roberts

如果您的 scrollView 是某种类型的 containerView 的子视图,请确保您的 scrollViewcontainerView 的框架或边界内。我有 containerView.clipsToBounds = NO,它仍然允许我看到滚动视图,但因为 scrollView 不在 containerView 的范围内,它不会检测到触摸事件。

例如:

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

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


J
Jagat Dave

viewDidLayoutSubviews 中添加以下代码对我来说适用于自动布局。尝试所有答案后:

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

}

//set the height of content size as required

W
Wissa

直接的编程方式

把它包起来

创建一个 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),
])

参考:Using UIScrollView with Auto Layout in iOS


H
H. de Jonge

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

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

您在 contentview 和 scrollview 之间设置为边距的约束不会影响 contentview 的大小。他们真的是利润。为了让它工作,内容视图应该有一个固定的大小。固定大小的诀窍是您可以将内容视图的宽度设置为等于滚动视图父级的宽度。只需选择左侧树中的两个视图并添加等宽约束。

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


@PredragManojlovic 它怎么能比这更通用?这是我可以使用自动布局让滚动视图正常工作的唯一方法。
K
Kuldeep

我发现这个 AutoLayout 问题...如果我只是让 ViewController 使用 UIView 而不是 UIScrollView 作为类...然后只需添加一个 UIScrollView 我自己...它可以工作。


N
Nandu

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

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

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

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


b
bobby123uk

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

Technical Note TN2154


B
Benjamin

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

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