UIScrollView 仅在任意 App 交互后有效

Posted

技术标签:

【中文标题】UIScrollView 仅在任意 App 交互后有效【英文标题】:UIScrollView Only Works After Arbitrary App Interaction 【发布时间】:2016-07-15 16:07:13 【问题描述】:

我知道这是 this 问题的重复,但问题似乎已被放弃,提问者未提供反馈,当前的答案对我不起作用。

我目前有一个简单的应用程序,其主视图包含一个 UIScrollView。当应用程序首次安装并运行时,没有滚动行为并且视图卡在内容视图的顶部,这不是预期的功能。通过旋转设备、触摸文本字段或触摸分段控件与应用程序交互都可以纠正滚动功能(即能够滚动到内容视图的底部):

为什么会发生这种行为? 如何解决?

详情:

与应用交互后,可以将其置于后台并重新打开,而不会丢失滚动功能。从后台手动终止应用程序并重新打开它将重新触发问题。最终目标是让滚动功能​​立即正确工作,而无需用户执行任意仪式来解锁应用程序的部分功能(Apple 的 HMI 指南中强烈反对)。

有问题的 UIScrollView (scrollView) 嵌入在最顶层的 UIView 中,并且它有一个 UIView (scrollContentView) 作为子项。 scrollView 的 contentSize.height 是在我的 viewWillLayoutSubviews() 函数中以编程方式定义的,这是 UIScrollView 在执行上述操作之一后使用的高度:

override func viewWillLayoutSubviews()

   super.viewWillLayoutSubviews();

   // (This is just setting a child table of the scrollView's height)
   // Set the goal table's height to the height of its contents
   formulaTableHeightConstaint.constant = getGoalTableHeight();

   scrollView.contentSize.height = getGoalTableHeight() + Constants.formHeight;

在viewWillLayoutSubviews()函数的最后,如果我打印scrollView.contentSize.height,它会显示2000左右的大值,打印scrollView.frame.size.height会显示600左右的值。

尝试:

我尝试使用scrollView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: SomeArbitraryValues, right: 0)。这允许在第一次打开应用程序时立即滚动,但这种行为是不直观的,即使将bottom 设置为应该小于滚动内容高度的值,也允许应用程序滚动超过底部的一段距离内容。同样,设置较小的值通常会阻止视图滚动到内容的底部。根据我从文档中了解到的情况,这似乎是一个稍微不相关(并且可能很臭)的属性,可用于解决此问题(尽管我可能是错的)。同样,即使弄乱 contentInset 似乎会触发正确的滚动行为,但在滚动工作之前和之后打印 contentInset 值显示它没有发生任何变化。 我还尝试向 scrollContentView 添加高度约束并以编程方式设置该高度无济于事。

非常感谢您对此事的任何帮助。

【问题讨论】:

我的猜测是 willLayoutSubviews 之后仅在 App Launch 上运行的东西正在改变你的滚动视图的值。我会在某处添加一个函数,当滚动视图无法正常工作时,您可以手动运行该函数来检查滚动视图内容高度。如果它在非活动状态下仍然显示正确的值,那么我离基地很远,不知道...... 所以我在整个代码中的多个位置运行了多次检查,在非活动状态下,scrollView.contentSize.height 始终显示良好的值 2497.5,所以这似乎不是问题。谢谢你的建议:) 还要检查这些地方的滚动视图本身的高度。它可能大于内容大小,或者高度为零。两者都会禁用滚动。 我检查了我能想到的每个 size 属性,多个位置的 scrollView,并且在不活动时,frame.size 或 bounds.size 总是显示 600, 600 【参考方案1】:

你应该如下设置 contentSize 高度:

scrollView.contentSize = CGSizeMake(width, getGoalTableHeight() + Constants.formHeight); 

scrollView.contentSize.height 指的是从contentSize 方法返回的结构的height 成员。

【讨论】:

这是一个很好的观点。仅设置高度可能不会触发内部方法来告诉 UI 发生了变化,现在它可以滚动了。 我用scrollView.contentSize = CGSizeMake(width, getGoalTableHeight() + Constants.formHeight); 替换了scrollView.contentSize.height = getGoalTableHeight() + Constants.formHeight; 仍然无济于事。很好的建议,谢谢:)

以上是关于UIScrollView 仅在任意 App 交互后有效的主要内容,如果未能解决你的问题,请参考以下文章

GZip 解压在任意点停止

LLDB – 在任意对象的实例变量上设置观察点

Word 自带公式编写多行公式时在任意位置对齐 -- 含视频教程(10)

在任意位置为stringbuffer 添加内容

在任意数量的数组之间找到共同项的最有效方法

使文本在任意背景图像上可读