it-swarm.com.de

Breite und Höhe gleich dem SuperView mit programmgesteuertem Autolayout?

Ich habe viele Schnipsel im Netz gesucht und finde immer noch keine Antwort auf mein Problem. Meine Frage ist, ich habe eine ScrollView (SV) und ich möchte eine Schaltfläche innerhalb von ScrollView (SV) programmgesteuert mit derselben Breite und Höhe des Superview, die ScrollView (SV) ist, hinzufügen, so dass beim Drehen des Geräts die Schaltfläche den gleichen Rahmen hat von scrollView (SV). Wie mache ich die NSLayout/NSLayoutConstraint? Vielen Dank

77
Bordz

Ich bin nicht sicher, ob dies der effizienteste Weg ist, aber es funktioniert.

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];
68
Bordz

Wenn jemand nach einer Swift-Lösung sucht - würde ich eine Swift -Erweiterung für UIViewerstellen, die Ihnen jedes Mal hilft, wenn Sie einen Subviews-Frame an seine Überwachungsgrenzen binden möchten:

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

    }
}

Dann einfach so nennen :

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

Dieser Link kann Ihnen helfen, folgen Sie den Anweisungen: http://www.raywenderlich.com/20881/beginning-auto-layout-part-1-of-2

BEARBEITEN:

verwenden Sie das folgende Code-Snippet, wobei SubView Ihre Subivew ist.

[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)]];
46
abhilvare

addConstraint- und removeConstraint-Methoden für UIView werden nicht mehr unterstützt. Es empfiehlt sich daher, Constraints-Erstellungskomforts zu verwenden:

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
15
beryllium

Ansatz 1: Über die UIView-Erweiterung

Hier ist ein funktionaler Ansatz in Swift 3+ mit einem Vorbedingung anstelle einer print (die in der Konsole leicht zugrunde gehen kann). Dies wird Programmierfehler melden als fehlgeschlagene Builds.

Diese Erweiterung hinzufügen zu Ihrem Projekt:

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]))
        }
    }
}

Jetzt nennen Sie es einfach so:

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

Beachten Sie, dass die oben genannte Methode bereits integriert in mein HandyUIKit -Framework ist, wodurch auch praktische Hilfen für die Benutzeroberfläche in Ihr Projekt eingefügt werden.


Ansatz # 2: Verwenden eines Frameworks

Wenn Sie in Ihrem Projekt viel mit programmatischen Einschränkungen arbeiten arbeiten, empfehle ich Ihnen, SnapKit zu überprüfen. Dies macht das Arbeiten mit Einschränkungen viel einfacher einfacher und weniger fehleranfällig.

Befolgen Sie die Installationsanweisungen in den Dokumenten, um SnapKit in Ihr Projekt aufzunehmen. Dann import oben in Ihrer Swift-Datei:

import SnapKit

Jetzt können Sie dasselbe mit genau diesem Ziel erreichen:

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

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]))
    }

}
6
PLJNS

Swift 4 mit 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])
2
Masih

Nachfolgend zur @ Dschee-Lösung ist hier die Syntax von Swift 3.0: (Bitte beachten: dies ist nicht meine Lösung , ich habe es gerade für Swift 3.0 behoben)

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]))
}
0
James Larcombe

Als ergänzende Antwort und für diejenigen, die sich nicht gegen das Einbeziehen von Bibliotheken von Drittanbietern aussprechen, bietet die Bibliothek PureLayout eine Methode, um genau dies zu tun. Wenn die Bibliothek einmal installiert ist, ist das so einfach

myView.autoPinEdgesToSuperviewEdges()

Es gibt andere Bibliotheken, die je nach Geschmack ähnliche Funktionalität bieten können, z. Mauerwerk , Kartographie

0
Matt Pinkston

Ich musste den Überblick vollständig abdecken. Die anderen würden das bei Orientierungsänderungen nicht tun. Also habe ich eine neue geschrieben, die einen willkürlichen Größenmultiplikator von 20 verwendet. Fühlen Sie sich frei, um Ihre Bedürfnisse zu ändern. Beachten Sie auch, dass dieses Subview tatsächlich viel größer ist als das Superview, was sich von den Anforderungen unterscheiden kann.

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),
            ])
    }
}
0
Jonny