将视图添加到将拉伸以填充可用宽度的滚动视图 [英] Adding a view to a scroll view that will stretch to fill available width

查看:24
本文介绍了将视图添加到将拉伸以填充可用宽度的滚动视图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在情节提要中使用自动布局,没有代码,并且很难将滚动视图的内容视图中的视图拉伸以填充设备宽度.我知道问题是滚动视图宽度不明确,但是当我希望它始终拉伸以填充可用宽度(带有一些填充)时,我不确定如何使其不模糊.

在视图控制器中,我添加了一个带有 4 个约束的滚动视图:顶部、底部、前导、尾随到超级视图.我向滚动视图添加了一个视图,它将充当内容视图 - 所有子视图都将添加到内容视图中.它有 4 个约束:顶部、底部、前导、尾随滚动视图.然后我将我想要可见的视图(一个简单的红色框,具有固定的高度,但拉伸以填充屏幕宽度)添加到内容视图.它的约束是:拖尾到超级视图(15),通向超级视图(15),顶部到超级视图(15),底部到超级视图(15),高度等于60.

这会导致滚动视图宽度不明确,并且框架错位 - 它想将框视图的宽度设置为 0.

如何进行设置,使框视图拉伸以填充设备屏幕,解决滚动视图内容大小宽度歧义?

解决方案

在 iOS 11 及更高版本中,滚动视图有两套布局指南,一套用于可滚动内容,

在 iOS 11 之前,在没有 frameLayoutGuide 的情况下,您必须根据滚动视图的超视图设置子视图的约束,我在下面概述了该过程.但从 iOS 11 开始,以上是更直观的解决方案.

<小时>

您在问题中描述的约束等效于以下 VFL:

  • 滚动视图占据整个视图

    H:|[scrollView]|V:|[滚动视图]|

  • 红色视图高 60 pt,与滚动视图 contentSize 边缘的边距为 15:

    H:|-(15)-[redView]-(15)-|V:|-(15)-[redView(60)]-(15)-|

红色视图是模棱两可的,因为没有定义它的宽度.(红色视图和滚动视图之间的水平约束定义了滚动视图的 contentSize,而不是红色视图的宽度.参见 Apple 技术说明 2154.)

您可以通过添加一个约束来解决这种歧义,即红色视图比主视图窄 30pt.因此,通过 control 在红色视图和滚动视图的超级视图之间添加约束 - 从红色视图拖动到滚动视图(这可能是从文档大纲中最容易做到的):

然后选择等宽":

将红色视图定义为与主视图相同的宽度后,您现在必须更改该约束以修改常量以调整您在红色视图和滚动视图的 contentSize.因此,选择您刚刚添加的约束并对其进行编辑,将常量更改为 -30:

坦率地说,Interface Builder 技术有点麻烦.以编程方式说明如何执行此操作可能更容易:

view.addConstraint(NSLayoutConstraint(item: redView, attribute: .Width, relatedBy: .Equal, toItem: view, attribute: .Width, multiplier: 1.0, constant: -30))

I am using Auto Layout in a storyboard, no code, and am having difficulties in getting the view inside the scroll view's content view to stretch to fill the device width. I understand the issue is an ambiguous scroll view width, but I'm not sure how to make it non-ambiguous when I want it to always stretch to fill available width (with some padding).

In a view controller, I added a scroll view with 4 constraints: top, bottom, leading, trailing to superview. I added a view to the scroll view that will act as the content view - all subviews will be added to the content view. It has 4 constraints: top, bottom, leading, trailing to scroll view. I then added the view I want to be visible (a simple red box that has a fixed height but stretches to fill the screen width) to the content view. Its constraints are: trailing to superview (15), leading to superview (15), top to superview (15), bottom to superview (15), and height equals 60.

This results in an ambiguous scroll view width, and the frames are misplaced - it wants to set the box view's width to 0.

How can I set this up so the box view stretches to fill the device screen, resolving the scroll view content size width ambiguity?

解决方案

In iOS 11 and later, scroll views have two sets of layout guides, one for the scrollable content, contentLayoutGuide (which dictates the scrolling behavior), and one for its frame, frameLayoutGuide (which dictates the size of the subview).

For example, this adds a subview that is inset by 20 points all the way around, whose width is set relative to the frame of the scroll view, but has a fixed height:

let subview = UIView()
subview.translatesAutoresizingMaskIntoConstraints = false
subview.backgroundColor = .red
scrollView.addSubview(subview)

NSLayoutConstraint.activate([
    subview.leadingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.leadingAnchor, constant: 20),
    subview.trailingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.trailingAnchor, constant: -20),
    subview.topAnchor.constraint(equalTo: scrollView.contentLayoutGuide.topAnchor, constant: 20),
    subview.bottomAnchor.constraint(equalTo: scrollView.contentLayoutGuide.bottomAnchor, constant: -20),

    subview.heightAnchor.constraint(equalToConstant: 1000),
    subview.widthAnchor.constraint(equalTo: scrollView.frameLayoutGuide.widthAnchor, constant: -40),
])

You can also do this in IB, without any coding at all:

Prior to iOS 11, in the absence of the frameLayoutGuide, you had to set the subview’s constraints based upon the scroll view’s superview, and I outline that process below. But since iOS 11, the above is the more intuitive solution.


The constraints you described in your question are equivalent to the following VFL:

  • The scroll view occupies the entire view

    H:|[scrollView]|
    V:|[scrollView]|
    

  • The red view is 60 pt tall and has a margin of 15 to the edges of the scroll view's contentSize:

    H:|-(15)-[redView]-(15)-|
    V:|-(15)-[redView(60)]-(15)-|
    

The red view is ambiguous because there is nothing that defines its width. (The horizontal constraints between the red view and the scroll view define the scroll view's contentSize, not the red view's width. See Apple Technical Note 2154.)

You resolve this ambiguity by adding a constraint that says that the red view is 30pt narrower than the main view. So add constraint between red view an the scroll view's superview by control-dragging from the red view to the scroll view (and this is probably easiest to do from the document outline):

Then choose "equal widths":

Having defined the red view to be the same width of the main view, you now have to alter that constraint to modify the constant to adjust for the margins you supplied between the red view and the scroll view's contentSize. Thus, select that constraint you just added and edit it, changing the constant to -30:

Frankly, that Interface Builder technique is a little cumbersome. It may be easier to illustrate how to do this programmatically:

view.addConstraint(NSLayoutConstraint(item: redView, attribute: .Width, relatedBy: .Equal, toItem: view, attribute: .Width, multiplier: 1.0, constant: -30))

这篇关于将视图添加到将拉伸以填充可用宽度的滚动视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆