使用自动布局约束我遇到了UIScrollView的麻烦 . 我有以下视图层次结构,通过IB设置约束:
- ScrollView (leading, trailing, bottom and top spaces to superview)
-- ContainerView (leading, trailing, bottom and top spaces to superview)
--- ViewA (full width, top of superview)
--- ViewB (full width, below ViewA)
--- Button (full width, below ViewB)
ViewA和ViewB的初始高度为200点,但可以通过单击将其垂直扩展到400点的高度 . ViewA和ViewB通过更新其高度约束(从200到400)进行扩展 . 这是相应的片段:
if(self.contentVisible) {
heightConstraint.constant -= ContentHeight;
// + additional View's internal constraints update to hide additional content
self.contentVisible = NO;
} else {
heightConstraint.constant += ContentHeight;
// + additional View's internal constraints update to show additional content
self.contentVisible = YES;
}
[self.view setNeedsUpdateConstraints];
[UIView animateWithDuration:.25f animations:^{
[self.view layoutIfNeeded];
}];
我的问题是,如果两个视图都被扩展,我需要能够滚动查看整个内容,现在滚动不起作用 . 如何使用约束来更新滚动视图以反映ViewA和ViewB高度的变化?
到目前为止,我能想到的唯一解决方案是在动画后手动设置ContainerView的高度,这将是ViewA ViewB Button高度的总和 . 但我相信还有更好的解决方案吗?
谢谢
6 回答
我使用如下的纯结构
确保Button( THE LAST view )有一个约束(从底部到superview的垂直间距,即scrollview),在这种情况下,无论视图A和视图B发生什么变化,scrollView的高度都会相应地改变 .
我参考了这个伟大的在线book site .
只需阅读“创建滚动视图”部分,您应该有一个想法 .
我有类似的问题,我正在创建一个详细信息视图和使用Interface Builder与Auto布局是一个非常适合任务!
祝好运!
(其他资源:
有关auto layout for scroll view的堆栈溢出讨论 .
iOS 6有一个Release Notes谈论UIScrollView的Auto Layout支持 .
免费在线iOS book explanation关于滚动视图 . 这实际上对我帮助很大!
假设我们有这样的层次结构(Label1是ContentView的子视图; ContentView是ScrollView的子视图,ScrollView是viewcontroller视图的子视图):
ViewController's View ScrollView ContentView Label1 Label2 Label3
ScrollView以与viewcontroller视图正常的方式使用autolayout进行约束 .
ContentView被固定在scrollview的顶部/左侧/右侧/底部 . 这意味着你有一些约束使ContentView的上/下/前/后边缘被约束为等于ScrollView上的相同边 . 这是一个关键:这些约束是针对ScrollView的contentSize,而不是它的框架大小,如viewcontroller的视图所示 . 因此,它不会告诉ContentView与显示的ScrollView框架具有相同的框架大小,而是告诉Scrollview ContentView是其内容,因此如果contentview大于ScrollView框架,那么您可以滚动,就像设置scrollView.contentSize更大而scrollView.frame使内容可滚动 .
这是另一个关键:现在你必须在ContentView,Label1-3和Scrollview之外的任何其他东西之间有足够的约束,以便ContentView能够从这些约束中找出它的宽度和高度 .
因此,例如,如果您需要垂直滚动的标签集,则设置约束以使ContentView宽度等于ViewController视图的宽度,该宽度负责宽度 . 为了处理高度,将Label1顶部固定到ContentView顶部,将Label2顶部固定到Label1底部,将Label3顶部固定到Label2底部,最后(并且重要的是)将Label3的底部固定到ContentView的底部 . 现在它有足够的信息来计算ContentView的高度 .
我希望这给某人一个线索,因为我阅读了上面的帖子,仍然无法弄清楚如何正确地使ContentView的宽度和高度限制 . 我缺少的是将Label3的底部固定在ContentView的底部,否则ContentView如何知道它有多高(因为Label3将会浮动,并且没有约束告诉ContentView它的底部y位置在哪里) .
这是我如何使用容器视图布局纯自动布局UIScrollView的示例 . 我评论说要更清楚:
容器是标准的UIView,而body是UITextView
在我的例子中,'body'是一个UITextView,但它可能是其他任何东西 . 如果您正好使用UITextView,请注意,为了使其垂直增长,它必须具有在viewDidLayoutSubviews中设置的高度约束 . 所以在viewDidLoad中添加以下约束并保持对它的引用:
然后在viewDidLayoutSubviews中计算高度并更新约束的常量:
该需要第二个布局传递来调整UITextView的大小 .
使用此代码 . ScrollView setContentSize应该在主线程中调用async .
滚动视图每时每刻都应该知道其内容大小 . 内容大小是从scrollview的子视图推断出来的 . 将控制器属性映射到描述子视图高度的xib文件中的约束非常方便 . 然后在代码(动画块)中,您可以只更改这些约束属性的常量 . 如果需要更改整个约束,请保留对它的引用,以便稍后可以在父容器中更新它 .
我的滚动视图变体!
Dynamic
!高度:1)将
scroll view
添加到UIView
. 固定所有(顶部,底部,引导,轨迹)约束 .2)将
UIView
添加到Scroll View
. 固定所有(顶部,底部,引导,轨迹)约束 . 这将是你的Content view
. 您也可以重命名它 .3)控制拖动从
Content view
到Scroll view
-Equal width
4)将内容添加到
UIView
. 设置所需的约束 . 和!在较低的项目添加底部约束 NOTGreater or equal
(>=
)(像大多数人谈话) BUTEqual
!例如,将其设置为20
.在我的情况下,我的内容是
UIImageView
. 我已将它的height
连接到代码 . 如果我将其更改为1000
,则滚动显示 . 一切正常 .对我来说就像一个魅力 . 有任何问题 - 欢迎提出意见 .