569 Stimmen

Wie man programmatisch Einschränkungen mit Swift hinzufügt

Ich versuche das seit letzter Woche herauszufinden, ohne einen Schritt weiter zu machen. Ok, also muss ich einige Einschränkungen programmgesteuert in Swift auf eine UIView anwenden, indem ich diesen Code verwende:

var new_view:UIView! = UIView(frame: CGRectMake(0, 0, 100, 100));
new_view.backgroundColor = UIColor.redColor();
view.addSubview(new_view);

var constX:NSLayoutConstraint = NSLayoutConstraint(item: new_view, attribute: NSLayoutAttribute.CenterX, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.CenterX, multiplier: 1, constant: 0);
self.view.addConstraint(constX);

var constY:NSLayoutConstraint = NSLayoutConstraint(item: new_view, attribute: NSLayoutAttribute.CenterY, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.CenterY, multiplier: 1, constant: 0);
self.view.addConstraint(constY);

var constW:NSLayoutConstraint = NSLayoutConstraint(item: new_view, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: new_view, attribute: NSLayoutAttribute.Width, multiplier: 1, constant: 0);
self.view.addConstraint(constW);

var constH:NSLayoutConstraint = NSLayoutConstraint(item: new_view, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: new_view, attribute: NSLayoutAttribute.Height, multiplier: 1, constant: 0);
self.view.addConstraint(constH);

Aber Xcode gibt diese seltsame Ausgabe zurück:

2014-10-03 09:48:12.657 Test[35088:2454916] Kann die Constraints nicht gleichzeitig erfüllen. Wahrscheinlich ist mindestens einer der Constraints in folgender Liste nicht gewünscht. Versuche dies: (1) betrachte jeden Constraint und versuche herauszufinden, welchen du nicht erwartest; (2) finde den Code, der den unerwünschten Constraint oder die unerwünschten Constraints hinzugefügt hat, und behebe es. (Hinweis: Wenn du NSAutoresizingMaskLayoutConstraints siehst, die du nicht verstehst, siehe die Dokumentation der UIView-Eigenschaft translatesAutoresizingMaskIntoConstraints) 
(
"",
"",
"",
""
)

Es wird versucht, den Constraint  aufzulösen.

Setze einen symbolischen Haltepunkt bei UIViewAlertForUnsatisfiableConstraints, um dies im Debugger zu erkennen. Die Methoden in der Kategorie UIConstraintBasedLayoutDebugging auf UIView in  könnten ebenfalls hilfreich sein.

2014-10-03 09:48:12.658 Test[35088:2454916] Kann die Constraints nicht gleichzeitig erfüllen. Wahrscheinlich ist mindestens einer der Constraints in folgender Liste nicht gewünscht. Versuche dies: (1) betrachte jeden Constraint und versuche herauszufinden, welchen du nicht erwartest; (2) finde den Code, der den unerwünschten Constraint oder die unerwünschten Constraints hinzugefügt hat, und behebe es. (Hinweis: Wenn du NSAutoresizingMaskLayoutConstraints siehst, die du nicht verstehst, siehe die Dokumentation der UIView-Eigenschaft translatesAutoresizingMaskIntoConstraints)
(
"",
"",
"",
""
)

Es wird versucht, den Constraint  aufzulösen.

Setze einen symbolischen Haltepunkt bei UIViewAlertForUnsatisfiableConstraints, um dies im Debugger zu erkennen. Die Methoden in der UIConstraintBasedLayoutDebugging-Kategorie auf UIView in  können ebenfalls hilfreich sein.

Kannst du mir helfen? Vielen Dank

294voto

Suragch Punkte 420096

Es hilft mir, visuell zu lernen, daher handelt es sich hier um eine ergänzende Antwort.

Boilerplate Code

override func viewDidLoad() {
    super.viewDidLoad()

    let myView = UIView()
    myView.backgroundColor = UIColor.blue
    myView.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(myView)

    // Hier den Constraints-Code hinzufügen
    // ...
}

Jedes der folgenden Beispiele ist unabhängig voneinander.

Linke Kante anheften

myView.leading = leadingMargin + 20

Bildbeschreibung hier eingeben

Methode 1: Anchor-Stil

let margins = view.layoutMarginsGuide
myView.leadingAnchor.constraint(equalTo: margins.leadingAnchor, constant: 20).isActive = true
  • Neben leadingAnchor gibt es auch trailingAnchor, topAnchor und bottomAnchor.

Methode 2: NSLayoutConstraint-Stil

NSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.leading, relatedBy: NSLayoutRelation.equal, toItem: view, attribute: NSLayoutAttribute.leadingMargin, multiplier: 1.0, constant: 20.0).isActive = true
  • Neben .leading gibt es auch .trailing, .top und .bottom.
  • Neben .leadingMargin gibt es auch .trailingMargin, .topMargin und .bottomMargin.

Breite und Höhe festlegen

width = 200
height = 100

Bildbeschreibung hier eingeben

Methode 1: Anchor-Stil

myView.widthAnchor.constraint(equalToConstant: 200).isActive = true
myView.heightAnchor.constraint(equalToConstant: 100).isActive = true

Methode 2: NSLayoutConstraint-Stil

NSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.width, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: 200).isActive = true
NSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.height, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: 100).isActive = true

In Container zentrieren

myView.centerX = centerX
myView.centerY = centerY

Bildbeschreibung hier eingeben

Methode 1: Anchor-Stil

myView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
myView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true

Methode 2: NSLayoutConstraint-Stil

NSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.centerX, relatedBy: NSLayoutRelation.equal, toItem: view, attribute: NSLayoutAttribute.centerX, multiplier: 1, constant: 0).isActive = true
NSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.centerY, relatedBy: NSLayoutRelation.equal, toItem: view, attribute: NSLayoutAttribute.centerY, multiplier: 1, constant: 0).isActive = true

Notizen

  • Der Anchor-Stil ist die bevorzugte Methode gegenüber dem NSLayoutConstraint-Stil, jedoch ist er erst ab iOS 9 verfügbar. Wenn Sie also iOS 8 unterstützen, sollten Sie den NSLayoutConstraint-Stil verwenden.
  • Die oben gezeigten Beispiele zeigten nur die ein oder zwei Constraints, auf die sich konzentriert wurde. Um jedoch myView in meinem Testprojekt richtig zu platzieren, brauchte ich vier Constraints.

Weitere Informationen

51voto

Josh Homann Punkte 16101

Wenn Sie Ihren Überblick füllen möchten, empfehle ich den swifty Weg:

view.translatesAutoresizingMaskIntoConstraints = false
let attributes: [NSLayoutAttribute] = [.top, .bottom, .right, .left]
NSLayoutConstraint.activate(attributes.map {
    NSLayoutConstraint(item: view, attribute: $0, relatedBy: .equal, toItem: view.superview, attribute: $0, multiplier: 1, constant: 0)
})

Andernfalls, wenn Sie ungleiche Einschränkungen benötigen, schauen Sie sich NSLayoutAnchor ab iOS 9 an. Oft ist es viel einfacher zu lesen als NSLayoutConstraint direkt:

view.translatesAutoresizingMaskIntoConstraints = false
view.topAnchor.constraint(equalTo: view.superview!.topAnchor).isActive = true
view.bottomAnchor.constraint(equalTo: view.superview!.bottomAnchor).isActive = true
view.leadingAnchor.constraint(equalTo: view.superview!.leadingAnchor, constant: 10).isActive = true
view.trailingAnchor.constraint(equalTo: view.superview!.trailingAnchor, constant: 10).isActive = true

41voto

Dilan Punkte 2597

Wir können das leicht mit in Swift 5+ tun

Setup 1

  • Subview wird auf das Zentrum der Ansicht ausgerichtet

  • Subview Breite und Höhe werden mithilfe von Float festgelegt

     view.addSubview(myView1)
     myView1.translatesAutoresizingMaskIntoConstraints = false
     NSLayoutConstraint.activate([
         myView1.centerXAnchor.constraint(equalTo: view.centerXAnchor),
         myView1.centerYAnchor.constraint(equalTo: view.centerYAnchor),
         myView1.widthAnchor.constraint(equalToConstant: 100),
         myView1.heightAnchor.constraint(equalToConstant: 100),
     ])

Setup 2

  • Subview wird auf das führende und obere Anker der Ansicht ausgerichtet

  • Subview Breite wird mithilfe der Ansichtsbreite und -höhe festgelegt

         view.addSubview(myView2)
         myView2.translatesAutoresizingMaskIntoConstraints = false
    
         NSLayoutConstraint.activate([
             myView2.leadingAnchor.constraint(equalTo: view.leadingAnchor,constant: 16),
             myView2.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor,constant: 16),
             myView2.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.3),
             myView2.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.3)
         ])

33voto

Rizwan Mehboob Punkte 1363

Einschränkungen für mehrere Ansichten im Spielplatz.

swift 3+

  var yellowView: UIView!
    var redView: UIView!

    override func loadView() {

        // UI

        let view = UIView()
        view.backgroundColor = .white

        yellowView = UIView()
        yellowView.backgroundColor = .yellow
        view.addSubview(yellowView)

        redView = UIView()
        redView.backgroundColor = .red
        view.addSubview(redView)

        // Layout
        redView.translatesAutoresizingMaskIntoConstraints = false
        yellowView.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            yellowView.topAnchor.constraint(equalTo: view.topAnchor, constant: 20),
            yellowView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20),
            yellowView.widthAnchor.constraint(equalToConstant: 80),
            yellowView.heightAnchor.constraint(equalToConstant: 80),

            redView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -20),
            redView.trailingAnchor.constraint(equalTo: view.trailingAnchor,constant: -20),
            redView.widthAnchor.constraint(equalToConstant: 80),
            redView.heightAnchor.constraint(equalToConstant: 80)
            ])

        self.view = view
    }

Meiner Meinung nach ist der Xcode-Spielplatz der beste Ort zum Lernen, wie man Constraints programmgesteuert hinzufügt.

Playground Bild

18voto

Avinash Reddy Punkte 496

Im Grunde genommen umfasste es 3 Schritte

fileprivate func setupName() { 

    lblName.text = "Hallo Welt"

    // Schritt 1
    lblName.translatesAutoresizingMaskIntoConstraints = false

    //Schritt 2
    self.view.addSubview(lblName)

    //Schritt 3
    NSLayoutConstraint.activate([
        lblName.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
        lblName.centerYAnchor.constraint(equalTo: self.view.centerYAnchor)
    ])
}

Dadurch wird das Label "Hallo Welt" in die Mitte des Bildschirms platziert.

Bitte beachten Sie den Link Autolayout constraints programmatisch

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X