iOS 7 autolayout of view embeded in scrolling view

2019-08-14 20:45发布

Here is probably, next stupid question from iOS newbie, what I'm experimenting is scrolling and auto layout stuff.

So I've created storyboard and added one view embedded by scrolling view. View has white background and I set scrolling view background to be blue:

enter image description here

Constraints you see all have 0 value, to match parent. In portrait mode everything fine:

enter image description here

But in landscape not, the leaf view not resized and scrolling view (blue one area at the right becomes visible)

enter image description here

1条回答
对你真心纯属浪费
2楼-- · 2019-08-14 21:38

The trick with scroll views is that the auto-layout constraints you add between the scroll view and its subviews will dictate the contentSize of the scroll view, not the size of the subviews themselves. See Technical Note TN2154 - UIScrollView And Autolayout. This actually is an incredibly useful feature (we no longer have to manually calculate/adjust contentSize), but it makes it unintuitive to make a subview resize based upon the screen's dimensions.

If you want the scroll view's subview to change its size as you go from portrait to landscape, you can add a constraint between the scroll view's subview and the root view (i.e. between the subview and its superview's superview). This doesn't replace the constraints between the scroll view and its subviews (which you still need to dictate the scroll view's contentSize), but supplements it so that the subview changes width as the root view does.

You can do this by expanding the document outline and control-dragging (or right-click-dragging) from the subview to the root view:

enter image description here

You can then specify to make their widths equal:

enter image description here

When you do this, the scroll view's subview will change width as the orientation changes. Here is the recursiveDescription of a 200 point tall subview when the device was in portrait:

(lldb) po [[UIWindow keyWindow] recursiveDescription]
<UIWindow: 0x8cbba70; frame = (0 0; 320 480); autoresize = W+H; gestureRecognizers = <NSArray: 0x8cbbca0>; layer = <UIWindowLayer: 0x8cbb4a0>>
   | <UIView: 0x8cbd990; frame = (0 0; 320 480); autoresize = RM+BM; layer = <CALayer: 0x8cbd040>>
   |    | <UIScrollView: 0x8cbdb70; frame = (0 0; 320 480); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x8cc19a0>; layer = <CALayer: 0x8cbd440>; contentOffset: {0, 0}>
   |    |    | <UIView: 0x8cbdf00; frame = (0 0; 320 200); autoresize = W+H; layer = <CALayer: 0x8cbdf60>>

And when I went into landscape, that last subview's width changed automatically:

(lldb) po [[UIWindow keyWindow] recursiveDescription]
<UIWindow: 0x8cbba70; frame = (0 0; 320 480); autoresize = W+H; gestureRecognizers = <NSArray: 0x8cbbca0>; layer = <UIWindowLayer: 0x8cbb4a0>>
   | <UIView: 0x8cbd990; frame = (0 0; 320 480); transform = [0, -1, 1, 0, 0, 0]; autoresize = RM+BM; layer = <CALayer: 0x8cbd040>>
   |    | <UIScrollView: 0x8cbdb70; frame = (0 0; 480 320); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x8cc19a0>; layer = <CALayer: 0x8cbd440>; contentOffset: {0, 0}>
   |    |    | <UIView: 0x8cbdf00; frame = (0 0; 480 200); autoresize = W+H; layer = <CALayer: 0x8cbdf60>>

Clearly, you can do the same thing with the height, too. In this example, I just had a height constraint that fixed the height at 200 pt, but do whatever you want.

You can obviously also go "old school" and respond to layout events to programmatically adjust constraints of subviews, but the above technique eliminates the need to do that.

查看更多
登录 后发表回答