UIScrollView可滚动内容大小模糊
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UIScrollView可滚动内容大小模糊相关的知识,希望对你有一定的参考价值。
各位开发者,我在Interface Builder(Xcode 5 / ios 7)中遇到AutoLayout问题。这是非常基本和重要的,所以我想每个人都应该知道这是如何正常运作的。如果这是Xcode中的一个错误,它是一个关键的错误!
所以,每当我有一个像这样的视图层次结构时,我遇到了麻烦:
>UIViewController
>> UIView
>>>UIScrollView
>>>>UILabel (or any other comparable UIKit Element)
UIScrollView具有可靠的约束条件,例如每边50 px(没问题)。然后我向UILabel添加一个Top Space约束(没问题)(我甚至可以固定标签的高度/宽度,不做任何改变,但由于Label的内在大小,应该是不必要的)
当我向UILabel添加尾随约束时,麻烦就开始了:
例如,尾随空间:Superview Equals:25
现在出现了两个警告 - 我不明白为什么:
A)可滚动内容大小歧义(滚动视图具有不明确的可滚动内容高度/宽度)
B)错位视图(预期标签:x = -67实际值:x = 207
我在一个新的项目中做了这个最小的例子,你可以下载并附上截图。如您所见,Interface Builder期望Label位于UIScrollView边界之外(橙色虚线矩形)。使用Resolve Issues Tool更新Label的框架会将其移动到那里。
请注意:如果用UIView替换UIScrollView,行为就像预期的那样(Label的框架是正确的,并且根据约束条件)。所以似乎UIScrollView存在问题,或者我错过了重要的事情。
当我按照IB的建议运行应用程序而不更新Label的框架时,它定位得很好,正好在它应该是的位置,并且UIScrollView是可滚动的。如果我更新框架,标签不在视线范围内,UIScrollView不会滚动。
帮助我Obi-Wan Kenobi!为什么模棱两可的布局?为什么错位的观点?
你可以在这里下载示例项目,如果你能弄清楚发生了什么就试试:https://github.com/Wirsing84/AutoLayoutProblem
注意:在iOS> 10.0上,尚未经过测试;因此,在某些情况下解决方案可能不完整。
所以我只是这样整理出来:
- 在
UIScrollView
里面添加一个UIView
(我们可以称之为contentView
); - 在这个
contentView
中,将顶部,底部,左侧和右侧边距设置为0(当然来自scrollView
,即superView
);设置水平和垂直对齐中心;
成品。
现在,您可以在contentView
中添加所有视图,contentSize
的scrollView
将根据contentView
自动调整大小。
更新:
@Matteo Gobbi的答案是完美的,但在我的情况下,scrollview无法滚动,我删除“对齐中心Y”并添加“height> = 1”,scrollview将变为可滚动
对我来说,添加一个contentView
并没有像建议的那样真正起作用。此外,由于添加了视图,它会产生开销(尽管我不认为这是一个大问题)。对我来说最有效的只是关闭我的scrollView
的歧义检查。一切都很顺利,所以我认为在像我这样的简单案例中也没关系。但请记住,如果你的scrollView
的其他限制中断,Interface-Builder将不再警告你了。
正在努力使用uiscrollview不滚动的人只需使用上一个视图的底部布局(位于内容视图内部)设置内容视图的底部约束。不要忘记删除中心Y约束。
休息所有约束与上面定义的相同。 Scrollview只关注从内容视图中获取最大高度,我们将其设置为最后视图的底部约束,这意味着scrollview会自动更改其内容偏移量。
在我的情况下,最后一个视图是UILable,没有行属性= 0(根据其内容自动调整其高度),因此它动态增加uilable的高度,最终我们的可滚动区域增加,因为uilable的底部布局与我们的内容视图的底部对齐,这会强制scrollview增加它的内容偏移量。
我通过使用“解决自动布局问题”>“为所选视图添加缺少的约束”解决了我的观点这种问题
以下两个约束解决了我的问题:
trailing = Stack View.trailing - 10
bottom = Stack View.bottom + 76
其中:trailing,bottom是UIScrollView的尾随底部
我在youTube上制作了一个视频 Scroll StackViews using only Storyboard in Xcode
我认为这里可以出现两种情景。
scrollView中的视图 -
- 没有任何内在的内容大小(例如
UIView
) - 确实有自己的内在内容大小(例如
UIStackView
)
对于两种情况下的垂直可滚动视图,您需要添加以下约束:
- 顶部,左侧,底部和右侧有4个约束。
- 滚动视图的宽度相等(停止水平滚动)
对于具有其内在内容高度的视图,您不需要任何其他约束。
对于没有任何内在内容高度的视图,您需要添加高度约束。仅当高度约束大于scrollView的高度时,视图才会滚动。
使用contentView(UView
)作为UIScrollView
内部的容器,坚持superview(top
)的边缘(bottom
,trailing
,leading
,UIScrollView
)和contentView
应该有equalwidth
和equalheight
到superview。这些是限制因素。并调用方法:
-(void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
self.scrollView.contentSize = self.contentView.frame.size;
}
解决了我的问题。
我所做的是创建一个单独的内容视图,如下所示。
内容视图是自由形式的,并且可以使用与contentView相关的自己的约束添加所有子视图。
UIScrollView将添加到主视图控制器中。
以编程方式,我将通过IBOutlet链接的contentView添加到类中,并设置UIScrollView的contentView。
我得到了同样的错误..我做了以下
- 查看(上海华)
- ScrollView 0,0,600,600
- UIView里面的ScrollView:0,0,600,600
- UIView包含图像视图,标签
现在为scrollView(2)添加前导/尾随/顶部/底部,然后添加UIView(3)。
选择View(1)和View(3)设置相同的高度和重量..它解决了我的问题。
我做了有助于的视频:
https://www.youtube.com/watch?v=s-CPN3xZS1A
[在XCode 7.2和iOS 9.2中测试]
为我设置故事板错误和警告的原因是将滚动视图和内容视图(在我的情况下是一个堆栈视图)的内在大小设置为占位符。此设置位于Storyboard中的“大小”检查器中。它说 - 设置设计时内在内容大小只影响在Interface Builder中编辑时的视图。视图在运行时不会具有此内在内容大小。
所以,我想通过设置它我们不会出错。
注意:在故事板中,我已将scrollview的所有边缘固定到superview,并将stackview的所有边缘固定到scrollview。在我的代码中,我为scrollview和stackview设置了translatesAutoresizingMaskIntoConstraints为false。我还没有提到内容大小。当堆栈视图动态增长时,故事板中设置的约束可确保堆栈可滚动。
故事板警告让我发疯,我不想让水平或垂直居中只是为了抑制警告。
如果有人发现你注意到右侧滚动条滚动但内容不移动的行为,这个事实可能值得考虑:
您还可以在滚动视图的内容和滚动视图外部的对象之间使用约束,以便为滚动视图的内容提供固定位置,使该内容看起来浮动在滚动视图上。
这是来自Apple的documentation。例如,如果您不小心将顶部的Label / Button / Img / View固定到滚动区域外的视图(也许是滚动视图上方的标题或某些内容?)而不是contentView,则会冻结整个contentView。
这个错误花了我一段时间来追踪,最初我尝试固定ScrollView的大小,但错误信息清楚地说“内容大小”。我确保从ScrollView顶部固定的所有内容也固定在底部。这样,ScrollView可以通过查找所有对象和约束的高度来计算其内容高度。这解决了模糊的内容高度,宽度非常相似......最初我在ScrollView中居住了大部分X,但我还必须将对象固定到ScrollView的侧面。我不喜欢这样,因为iPhone6可能有更宽的屏幕,但它会消除“模糊内容宽度”错误。
如前面的答案中所述,您应该在滚动视图中添加自定义视图:
将所有子视图添加到内容视图中。在某些时候,您将看到滚动内容视图具有不明确的内容大小警告,您应该选择内容视图并单击“解决自动布局问题”按钮(在IB布局的右下角),然后选择“添加缺失”约束“选项。
从现在开始运行项目时,滚动视图将自动更新其内容大小,无需其他代码。
您只需要确保有一种方法可以从滚动视图的顶部到底部形成连续的约束线。 [-X-X-X]
在我的情况下 - 水平滚动滚动视图 - 我还需要为滚动视图的每个子项添加宽度和高度约束,尽管Apple's technical note没有告诉你这一点。
在Interface Builder的大小检查器中将ViewController(持有UIScrollView的那个)大小设置为Freeform,所有这些都应该有效。
Freeform setting in Size inspector in Interface Builder for the containing UIViewcontroller
Swift 4+方法:
1)将UIScrollView的上,下,左,右边距设置为0
2)在UIScrollView内部添加一个UIView并将顶部,底部,前导,尾随边距设置为0(等于UIScrollView边距)。
3)最重要的部分是设置宽度和高度,其中高度约束应该具有低优先级。
private func setupConstraints() {
// Constraints for scrollView
scrollView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
// Constraints for containerView
containerView.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true
containerView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true
containerView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor).is以上是关于UIScrollView可滚动内容大小模糊的主要内容,如果未能解决你的问题,请参考以下文章
带有空 UIScrollView 的可滚动内容大小歧义(XCode 6)
Swift:以编程方式添加视图时,UIScrollView 的可滚动内容大小不明确,而不使用 IB