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 交互后有效的主要内容,如果未能解决你的问题,请参考以下文章