Ios 宽度和高度是否等于以编程方式使用autolayout的superView?

Ios 宽度和高度是否等于以编程方式使用autolayout的superView?,ios,swift,dynamic,autolayout,nslayoutconstraint,Ios,Swift,Dynamic,Autolayout,Nslayoutconstraint,我一直在网上寻找很多片段,但仍然找不到问题的答案。我的问题是我有一个scrollView(SV),我想以编程方式在scrollView(SV)中添加一个按钮,其超视图的宽度和高度与scrollView(SV)相同,这样当用户旋转设备按钮时,它将具有相同的scrollView(SV)框架。如何执行NSLayout/NSLayout约束?谢谢此链接可以帮助您,请按照说明操作: 编辑: 使用下面的代码段,其中subview是您的子视图 [subview setTranslatesAutoresizin

我一直在网上寻找很多片段,但仍然找不到问题的答案。我的问题是我有一个scrollView(SV),我想以编程方式在scrollView(SV)中添加一个按钮,其超视图的宽度和高度与scrollView(SV)相同,这样当用户旋转设备按钮时,它将具有相同的scrollView(SV)框架。如何执行NSLayout/NSLayout约束?谢谢

此链接可以帮助您,请按照说明操作:

编辑:

使用下面的代码段,其中subview是您的子视图

[subview setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.view addConstraints:[NSLayoutConstraint
                           constraintsWithVisualFormat:@"H:|-0-[subview]-0-|"
                           options:NSLayoutFormatDirectionLeadingToTrailing
                           metrics:nil
                           views:NSDictionaryOfVariableBindings(subview)]];
[self.view addConstraints:[NSLayoutConstraint
                           constraintsWithVisualFormat:@"V:|-0-[subview]-0-|"
                           options:NSLayoutFormatDirectionLeadingToTrailing
                           metrics:nil
                           views:NSDictionaryOfVariableBindings(subview)]];

我不确定这是否是最有效的方法,但它是有效的

UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.translatesAutoresizingMaskIntoConstraints = NO;
// initialize


[coverForScrolView addSubview:button];

NSLayoutConstraint *width =[NSLayoutConstraint
                                    constraintWithItem:button
                                    attribute:NSLayoutAttributeWidth
                                    relatedBy:0
                                    toItem:coverForScrolView
                                    attribute:NSLayoutAttributeWidth
                                    multiplier:1.0
                                    constant:0];
NSLayoutConstraint *height =[NSLayoutConstraint
                                     constraintWithItem:button
                                     attribute:NSLayoutAttributeHeight
                                     relatedBy:0
                                     toItem:coverForScrolView
                                     attribute:NSLayoutAttributeHeight
                                     multiplier:1.0
                                     constant:0];
NSLayoutConstraint *top = [NSLayoutConstraint
                                   constraintWithItem:button
                                   attribute:NSLayoutAttributeTop
                                   relatedBy:NSLayoutRelationEqual
                                   toItem:coverForScrolView
                                   attribute:NSLayoutAttributeTop
                                   multiplier:1.0f
                                   constant:0.f];
NSLayoutConstraint *leading = [NSLayoutConstraint
                                       constraintWithItem:button
                                       attribute:NSLayoutAttributeLeading
                                       relatedBy:NSLayoutRelationEqual
                                       toItem:coverForScrolView
                                       attribute:NSLayoutAttributeLeading
                                       multiplier:1.0f
                                       constant:0.f];
[coverForScrolView addConstraint:width];
[coverForScrolView addConstraint:height];
[coverForScrolView addConstraint:top];
[coverForScrolView addConstraint:leading];

如果有人正在寻找Swift解决方案,我会为
UIView
创建一个Swift扩展,每当您想将子视图框架绑定到其SuperView边界时,它都会帮到您:

Swift 2:

extension UIView {

    /// Adds constraints to this `UIView` instances `superview` object to make sure this always has the same size as the superview.
    /// Please note that this has no effect if its `superview` is `nil` – add this `UIView` instance as a subview before calling this.
    func bindFrameToSuperviewBounds() {
        guard let superview = self.superview else {
            print("Error! `superview` was nil – call `addSubview(view: UIView)` before calling `bindFrameToSuperviewBounds()` to fix this.")
            return
        }

        self.translatesAutoresizingMaskIntoConstraints = false
        superview.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-0-[subview]-0-|", options: .DirectionLeadingToTrailing, metrics: nil, views: ["subview": self]))
        superview.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-0-[subview]-0-|", options: .DirectionLeadingToTrailing, metrics: nil, views: ["subview": self]))
    }

}
Swift 3:

extension UIView {

    /// Adds constraints to this `UIView` instances `superview` object to make sure this always has the same size as the superview.
    /// Please note that this has no effect if its `superview` is `nil` – add this `UIView` instance as a subview before calling this.
    func bindFrameToSuperviewBounds() {
        guard let superview = self.superview else {
            print("Error! `superview` was nil – call `addSubview(view: UIView)` before calling `bindFrameToSuperviewBounds()` to fix this.")
            return
        }

        self.translatesAutoresizingMaskIntoConstraints = false
        superview.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-0-[subview]-0-|", options: .directionLeadingToTrailing, metrics: nil, views: ["subview": self]))
        superview.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-0-[subview]-0-|", options: .directionLeadingToTrailing, metrics: nil, views: ["subview": self]))
    }
}
Swift 4.2:

extension UIView {

    /// Adds constraints to this `UIView` instances `superview` object to make sure this always has the same size as the superview.
    /// Please note that this has no effect if its `superview` is `nil` – add this `UIView` instance as a subview before calling this.
    func bindFrameToSuperviewBounds() {
        guard let superview = self.superview else {
            print("Error! `superview` was nil – call `addSubview(view: UIView)` before calling `bindFrameToSuperviewBounds()` to fix this.")
            return
        }

        self.translatesAutoresizingMaskIntoConstraints = false
        self.topAnchor.constraint(equalTo: superview.topAnchor, constant: 0).isActive = true
        self.bottomAnchor.constraint(equalTo: superview.bottomAnchor, constant: 0).isActive = true
        self.leadingAnchor.constraint(equalTo: superview.leadingAnchor, constant: 0).isActive = true
        self.trailingAnchor.constraint(equalTo: superview.trailingAnchor, constant: 0).isActive = true

    }
}
然后简单地这样称呼它:

// after adding as a subview, e.g. `view.addSubview(subview)`
subview.bindFrameToSuperviewBounds()

作为补充答案,对于那些不反对包括第三方库的人来说,库提供了一种方法来实现这一点。 一旦安装了库,就可以像

myView.autoPinEdgesToSuperviewEdges()
还有其他一些库也可以根据口味提供类似的功能,例如

Swift 3:

import UIKit

extension UIView {

    func bindFrameToSuperviewBounds() {
        guard let superview = self.superview else {
            print("Error! `superview` was nil – call `addSubview(view: UIView)` before calling `bindFrameToSuperviewBounds()` to fix this.")
            return
        }

        self.translatesAutoresizingMaskIntoConstraints = false
        superview.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-0-[subview]-0-|", options: .directionLeadingToTrailing, metrics: nil, views: ["subview": self]))
        superview.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-0-[subview]-0-|", options: .directionLeadingToTrailing, metrics: nil, views: ["subview": self]))
    }

}

作为@Dschee解决方案的后续,以下是swift 3.0语法: (请注意:这不是我的解决方案,我刚刚为Swift 3.0修复了它)

方法#1:通过UIView扩展 在Swift 3+中,这里有一个更实用的方法,它是一个先决条件,而不是
打印(在控制台中很容易消失)。这一个将作为失败的构建报告程序员错误

将此扩展添加到项目中:

extension UIView {
    /// Adds constraints to the superview so that this view has same size and position.
    /// Note: This fails the build if the `superview` is `nil` – add it as a subview before calling this.
    func bindEdgesToSuperview() {
        guard let superview = superview else {
            preconditionFailure("`superview` was nil – call `addSubview(view: UIView)` before calling `bindEdgesToSuperview()` to fix this.")
        }
        translatesAutoresizingMaskIntoConstraints = false
        ["H:|-0-[subview]-0-|", "V:|-0-[subview]-0-|"].forEach { visualFormat in
            superview.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: visualFormat, options: .directionLeadingToTrailing, metrics: nil, views: ["subview": self]))
        }
    }
}
现在只需这样称呼它

// after adding as a subview, e.g. `view.addSubview(subview)`
subview.bindEdgesToSuperview()
请注意,上面的方法已集成到我的框架中,该框架还向您的项目中添加了一些更方便的UI助手


方法2:使用框架 如果您在项目中大量使用编程约束,那么我建议您签出。它使处理约束变得更加容易,并且不容易出错

按照文档中的将SnapKit包含到项目中。然后将其导入Swift文件顶部:

import SnapKit
现在,您可以通过以下方式实现相同的目标:

subview.snp.makeConstraints { make in
    make.edges.equalToSuperview()
}

UIView的
addConstraint
removeConstraint
方法将被弃用,因此值得使用“约束创建便利性”:

view.topAnchor.constraint(equalTo: superView.topAnchor, constant: 0).isActive = true
view.bottomAnchor.constraint(equalTo: superView.bottomAnchor, constant: 0).isActive = true
view.leadingAnchor.constraint(equalTo: superView.leadingAnchor, constant: 0).isActive = true
view.trailingAnchor.constraint(equalTo: superView.trailingAnchor, constant: 0).isActive = true

Swift 4使用
NSLayoutConstraint

footerBoardImageView.translatesAutoresizingMaskIntoConstraints = false
let widthConstraint  = NSLayoutConstraint(item: yourview, attribute: NSLayoutAttribute.width, relatedBy: NSLayoutRelation.equal, toItem: superview, attribute: NSLayoutAttribute.width, multiplier: 1, constant: 0)
let heightConstraint = NSLayoutConstraint(item: yourview, attribute: NSLayoutAttribute.height, relatedBy: NSLayoutRelation.equal, toItem: superview, attribute: NSLayoutAttribute.height, multiplier: 1, constant: 0)
superview.addConstraints([widthConstraint, heightConstraint])

我需要完全覆盖superview。其他人在方向改变时不会这样做。所以我写了一个新的,使用任意大小的乘数20。随时根据您的需要进行更改。还要注意,这实际上使子视图比superview大得多,这可能与需求不同

extension UIView {
    func coverSuperview() {
        guard let superview = self.superview else {
            assert(false, "Error! `superview` was nil – call `addSubview(_ view: UIView)` before calling `\(#function)` to fix this.")
            return
        }
        self.translatesAutoresizingMaskIntoConstraints = false
        let multiplier = CGFloat(20.0)
        NSLayoutConstraint.activate([
            self.heightAnchor.constraint(equalTo: superview.heightAnchor, multiplier: multiplier),
            self.widthAnchor.constraint(equalTo: superview.widthAnchor, multiplier: multiplier),
            self.centerXAnchor.constraint(equalTo: superview.centerXAnchor),
            self.centerYAnchor.constraint(equalTo: superview.centerYAnchor),
            ])
    }
}

我从其他答案中挑选了最好的元素:

扩展UIView{ ///向“UIView”实例“superview”对象添加约束,以确保该对象始终具有与superview相同的大小。 ///请注意,如果其“superview”为“nil”,则此操作无效–在调用此操作之前,将此“UIView”实例添加为子视图。 func bindFrameToSuperviewBounds(){ guard let superview=self.superview-else{ print(“Error!`superview`was nil–在调用`bindFrameToSuperviewBounds()`修复此问题之前调用`addSubview(视图:UIView)` 返回 } self.translatesAutoResizengMaskintoConstraints=false NSLayoutConstraint.activate([ self.topAnchor.constraint(equalTo:superview.topAnchor), self.bottomAnchor.constraint(等式:superview.bottomAnchor), self.leadingAnchor.constraint(等同于:superview.leadingAnchor), self.trailingAnchor.constraint(equalTo:superview.trailingAnchor) ]) } }
您可以这样使用它,例如在自定义UIView中:

let myView=UIView()
myView.backgroundColor=UIColor.red
self.addSubview(myView)
myView.bindFrameToSuperviewBounds()文件

在这种情况下,可视格式也可以是
V:|[subview]|
H:|[subview]|
值得注意的是(几年后)此代码已经非常过时。现在添加约束要容易得多-请参见下面的任何答案,使用
NSLayoutConstraint会更有效。activateConstraints([width,height,top,leading])
您可以使用
[coverForScrolView addConstraints:@[width,height,top,leading]值得注意的是(几年后)此代码极为过时。现在添加约束条件要容易得多——请参见下面的任何2017年答案。如果您只是更改了代码以使其符合Swift 3,您应该编辑原始海报答案,而不是发布新答案(因为这并没有改变海报的原始意图)。如果你没有足够的分数进行编辑,那么就在原始帖子上发表评论,并提示需要进行哪些修改才能符合Swift 3。原始海报(或其他人看到你的评论)可能会更新答案。通过这种方式,我们可以避免重复答案和不推荐的代码。嘿@Dschee-我完全同意你的观点,但我们“错了”。网站上的“共识”观点无论好坏,都与你在这里表达的观点相反。(我一直忽视共识决定,做明智的事情,然后从mods中惹麻烦:))如果您只是更改代码使其符合Swift 3,您应该编辑原始海报答案,而不是发布新答案(因为这并没有改变海报的原始意图)。如果你没有足够的分数进行编辑,那么就用一个
extension UIView {
    func coverSuperview() {
        guard let superview = self.superview else {
            assert(false, "Error! `superview` was nil – call `addSubview(_ view: UIView)` before calling `\(#function)` to fix this.")
            return
        }
        self.translatesAutoresizingMaskIntoConstraints = false
        let multiplier = CGFloat(20.0)
        NSLayoutConstraint.activate([
            self.heightAnchor.constraint(equalTo: superview.heightAnchor, multiplier: multiplier),
            self.widthAnchor.constraint(equalTo: superview.widthAnchor, multiplier: multiplier),
            self.centerXAnchor.constraint(equalTo: superview.centerXAnchor),
            self.centerYAnchor.constraint(equalTo: superview.centerYAnchor),
            ])
    }
}