【问题标题】:Add Views to UIScrollView Programmatically以编程方式将视图添加到 UIScrollView
【发布时间】:2017-06-28 13:43:22
【问题描述】:

我已将以下代码添加到我的 UIViewController:

override func viewDidLoad() {
    super.viewDidLoad()

    viewBrochures.isUserInteractionEnabled = true
    let brochure1: UIImageView = UIImageView(image: UIImage(named: "image1")!)
    brochure1.translatesAutoresizingMaskIntoConstraints = false
    brochure1.contentMode = .scaleAspectFit
    brochure1.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 400)
    viewBrochures.addSubview(brochure1)
    let brochure2: UIImageView = UIImageView(image: UIImage(named: "image2")!)
    brochure2.translatesAutoresizingMaskIntoConstraints = false
    brochure2.contentMode = .scaleAspectFit
    brochure2.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 400)
    viewBrochures.addSubview(brochure2)
    let brochure3: UIImageView = UIImageView(image: UIImage(named: "image3")!)
    brochure3.translatesAutoresizingMaskIntoConstraints = false
    brochure3.contentMode = .scaleAspectFit
    brochure3.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 400)
    viewBrochures.addSubview(brochure3)
    let brochure4: UIImageView = UIImageView(image: UIImage(named: "image4")!)
    brochure4.translatesAutoresizingMaskIntoConstraints = false
    brochure4.contentMode = .scaleAspectFit
    brochure4.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 400)
    viewBrochures.addSubview(brochure4)


    viewBrochures.addConstraint(NSLayoutConstraint(item: brochure1,
                                                attribute: .trailing,
                                                    relatedBy: .equal,
                                                    toItem: viewBrochures,
                                                    attribute: .trailingMargin,
                                                    multiplier: 1,
                                                    constant: 0))
    viewBrochures.addConstraint(NSLayoutConstraint(item: brochure1,
                                                  attribute: .leading,
                                                  relatedBy: .equal,
                                                  toItem: viewBrochures,
                                                  attribute: .leadingMargin,
                                                  multiplier: 1,
                                                  constant: 0))
    viewBrochures.addConstraint(NSLayoutConstraint(item: brochure1,
                                                  attribute: .top,
                                                  relatedBy: .equal,
                                                  toItem: viewBottomButtons,
                                                  attribute: .bottom,
                                                  multiplier: 1,
                                                  constant: 10))
    viewBrochures.addConstraint(NSLayoutConstraint(item: brochure1,
                                                  attribute: .bottom,
                                                  relatedBy: .equal,
                                                  toItem: brochure2,
                                                  attribute: .top,
                                                  multiplier: 1,
                                                  constant: 10))


    viewBrochures.addConstraint(NSLayoutConstraint(item: brochure2,
                                                  attribute: .trailing,
                                                  relatedBy: .equal,
                                                  toItem: viewBrochures,
                                                  attribute: .trailingMargin,
                                                  multiplier: 1,
                                                  constant: 0))
    viewBrochures.addConstraint(NSLayoutConstraint(item: brochure2,
                                                  attribute: .leading,
                                                  relatedBy: .equal,
                                                  toItem: viewBrochures,
                                                  attribute: .leadingMargin,
                                                  multiplier: 1,
                                                  constant: 0))
    viewBrochures.addConstraint(NSLayoutConstraint(item: brochure2,
                                                  attribute: .top,
                                                  relatedBy: .equal,
                                                  toItem: brochure1,
                                                  attribute: .bottom,
                                                  multiplier: 1,
                                                  constant: 10))
    viewBrochures.addConstraint(NSLayoutConstraint(item: brochure2,
                                                  attribute: .bottom,
                                                  relatedBy: .equal,
                                                  toItem: brochure3,
                                                  attribute: .top,
                                                  multiplier: 1,
                                                  constant: 10))


    viewBrochures.addConstraint(NSLayoutConstraint(item: brochure3,
                                                  attribute: .trailing,
                                                  relatedBy: .equal,
                                                  toItem: viewBrochures,
                                                  attribute: .trailingMargin,
                                                  multiplier: 1,
                                                  constant: 0))
    viewBrochures.addConstraint(NSLayoutConstraint(item: brochure3,
                                                  attribute: .leading,
                                                  relatedBy: .equal,
                                                  toItem: viewBrochures,
                                                  attribute: .leadingMargin,
                                                  multiplier: 1,
                                                  constant: 0))
    viewBrochures.addConstraint(NSLayoutConstraint(item: brochure3,
                                                  attribute: .top,
                                                  relatedBy: .equal,
                                                  toItem: brochure2,
                                                  attribute: .bottom,
                                                  multiplier: 1,
                                                  constant: 10))
    viewBrochures.addConstraint(NSLayoutConstraint(item: brochure3,
                                                  attribute: .bottom,
                                                  relatedBy: .equal,
                                                  toItem: brochure4,
                                                  attribute: .top,
                                                  multiplier: 1,
                                                  constant: 10))


    viewBrochures.addConstraint(NSLayoutConstraint(item: brochure4,
                                                  attribute: .trailing,
                                                  relatedBy: .equal,
                                                  toItem: viewBrochures,
                                                  attribute: .trailingMargin,
                                                  multiplier: 1,
                                                  constant: 0))
    viewBrochures.addConstraint(NSLayoutConstraint(item: brochure4,
                                                  attribute: .leading,
                                                  relatedBy: .equal,
                                                  toItem: viewBrochures,
                                                  attribute: .leadingMargin,
                                                  multiplier: 1,
                                                  constant: 0))
    viewBrochures.addConstraint(NSLayoutConstraint(item: brochure4,
                                                  attribute: .top,
                                                  relatedBy: .equal,
                                                  toItem: brochure3,
                                                  attribute: .bottom,
                                                  multiplier: 1,
                                                  constant: 10))
    viewBrochures.addConstraint(NSLayoutConstraint(item: brochure4,
                                                  attribute: .bottomMargin,
                                                  relatedBy: .greaterThanOrEqual,
                                                  toItem: viewBrochures,
                                                  attribute: .bottom,
                                                  multiplier: 1,
                                                  constant: 10))

}

还有:

override func viewDidLayoutSubviews() {
    scrlMain.contentSize = viewBrochures.bounds.size
}

请注意,我已经在情节提要中设置了 UIScrollView 和容器视图 (viewBrochures),我只需要将图像添加到容器中,然后能够垂直滚动它们,因为它们不适合屏幕.在滚动视图的容器视图中,我已经有 2 个其他视图需要在这些新图像上方(图像需要在 2 个视图下方,并且所有这些视图(2 个视图 + 图像)需要在滚动视图中一起滚动)。其他 2 个视图已经添加到情节提要中,没有问题。如您所见,我已经创建了图像并以编程方式向它们添加了约束。我为每个图像添加了 4 个约束,一个用于前导,一个用于尾随,一个用于顶部,一个用于底部。我已将最顶部的图像约束到正上方视图的底部,而我已使用更大的ThanOrEqual 约束将最底部的图像约束到容器视图的底部。我还在 SO 上的某处看到,在代码中将图像添加到滚动视图时,需要向图像添加“translatesAutoresizingMaskIntoConstraints = false”,但我不确定它的作用以及是否需要。

所以这段代码适用于添加图像,但问题是滚动视图根本不会滚动。我不确定这是否是正确的方法,所以请随时向我建议任何其他选择。如您所见,我使用了自动布局和布局约束。如果您可以查看我的实施是否有任何问题,我们将不胜感激任何建议和/或更正。

【问题讨论】:

    标签: xcode uiscrollview swift3 autolayout nslayoutconstraint


    【解决方案1】:

    您的方法存在两个主要问题:

    1. 使用 AutoLayout 时,不应手动设置任何框架。 AutoLayout 会为您执行此操作,并且在您干扰时不喜欢它。
    2. 在使用 UIScrollViews 和 AutoLayout 时,您不应设置 UIScrollView 的 contentSize。只要您的约束设置正确,UIScrollView 就会自动调整其contentSize 并滚动其内容。

    此外,您实际上并不需要 viewBrochures 容器视图(除非它除了作为图像的容器之外做任何事情)。您可以简单地将上面的 2 个视图和所有图像添加为 UIScrollView 的直接子视图。

    要使滚动视图正常工作,您必须执行以下操作:

    1. 最顶层的子视图必须与 UIScrollView 有一个顶部约束
    2. 所有其他子视图必须有一个顶部约束,其上方子视图的底部约束
    3. 最底部的子视图必须与 UIScrollView 有底部约束

    您还必须注意子视图不要变得比您的滚动视图更宽(或者滚动视图也会突然水平滚动)。为此,您必须在等于滚动视图宽度的子视图之一上设置width 约束。

    如果您仍然难以使其正常工作,请查看我前段时间写的 blogpost,其中我描述了与您类似的场景。

    我还通过一个工作示例创建了这个gist

    【讨论】:

    • 嗨。感谢您的回答。我试过了,我删除了viewBrochures,并将所有视图直接放在ScrollView下面,并确保宽度不超过ScrollView的宽度但仍然没有运气......它仍然不会滚动。
    • 您是否删除了所有出现的 frame = ...contentSize = ... 的位置?
    • @joern “必须有一个顶部约束和底部约束”。但是没有定义底部约束。也不是高度(我无法定义它们,因为我使用的是重构的 UIViewController)。我的意思是,我昨天花了一整天的时间试图让这些愚蠢的限制发挥作用。按原样实施您的想法,我得到整个屏幕高度相同的所有视图相互重叠。除非是 Xcode 10 测试版,因为这让我发疯。
    • @MicheleDall'Agata 请看一下这个要点:gist.github.com/pixeldock/f1c3b2bf0f7fe48d412c09fcb2705bf1
    • @joern 找到了。这是 tvOS,很明显,我必须继承 UIView 来覆盖 canBecomeFocused:class myUIView: UIView { override var canBecomeFocused: Bool { return true } } - 今天我学到了一些新东西.. 谢谢你的要点,非常有帮助!
    猜你喜欢
    • 1970-01-01
    • 2012-02-29
    • 2017-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多