2017-01-07 3 views
1

Ich habe eine benutzerdefinierte Unterklasse von UIView in meiner iOS-Anwendung gemacht, und ich versuche, die berechneten Größen der Ansicht in der Ansicht init-Methode zu erhalten, damit ich sie beim Erstellen von Unteransichten verwenden kann in der benutzerdefinierten Ansicht.Größe von UIView in init

Die benutzerdefinierte Ansicht befindet sich in einer Stapelansicht, die meiner Ansicht 1/3 der Gesamtgröße (Hauptansicht) zuweist.

Mein init sieht wie folgt aus:

var mySubView: UIImageView 

required init?(coder aDecoder: NSCoder) { 

    mySubView = UIImageView() 
    super.init(coder: aDecoder) 

    let viewWidth = Int(self.frame.size.width) 
    let viewHeight = Int(self.frame.size.height) 
    mySubView.frame = CGRect(x: 0, y: 0, width: viewWidth, height: viewHeight) 
    mySubView.backgroundColor = UIColor.cyan 

    self.addSubview(mySubView) 
} 

jedoch die Höhen und Breiten sind nicht korrekt gemeldet. Zum Beispiel füllt mySubView oben nur etwa die Hälfte des gesamten Speicherplatzes der benutzerdefinierten Ansicht aus.

Jede Hilfe würde sehr geschätzt werden!

+0

Ich glaube nicht die Sicht weiß, dass es Dimensionen an dieser Stelle während seines Lebenszyklus. Versuchen Sie, die Dimensionen in 'viewWillAppear' zu erhalten – toddg

+4

Sie können nicht, nicht, wenn es die View-Controller-Ansicht ist. Es ist zu früh im Lebenszyklus des View-Controllers. Sie müssen warten, bis (frühestens) UIViewController.viewWillViewSubviews(). Aus diesem Grund sollten Sie wahrscheinlich Auto-Layout-Einschränkungen verwenden, von denen viele bereits in einer Stapelansicht behandelt werden. Erstellen Sie Ihre benutzerdefinierte Ansicht, fügen Sie die Untersichten und Einschränkungen (entweder in IB oder Code) zur benutzerdefinierten Ansicht hinzu, und die Elemente werden so angeordnet, wie Sie sie benötigen. – dfd

+1

@toddg ist korrekt, die Alternative zu viewWillLayoutSubviews() (verwendet von UIViewController) ist ViewWillAppear() (von UIView verwendet). Ich tendiere dazu, in Bezug auf den View-Controller zu denken. ACHTUNG: Ich glaube, dass beide Funktionen mehr als einmal beim Laden aufgerufen werden können, und auch auf Dinge wie Orientierungsänderungen (und im iPad, Multitasking). – dfd

Antwort

1

Der Initialisierer wird zu früh im Lebenszyklus der Ansicht aufgerufen, um das Layout genau auszuführen, sofern Sie die exakten Dimensionen nicht im Voraus kennen. Trotzdem ist es idiomatisch die falsche Ort, es zu tun.

Versuchen Sie, die layoutSubviews Methode als solche mit:

class SubView: UIImageView { 

    var mySubView: UIImageView 

    required init?(coder aDecoder: NSCoder) { 

     mySubView = UIImageView() 
     mySubView.backgroundColor = UIColor.cyan 

     super.init(coder: aDecoder) 
     self.addSubview(mySubView) 
    } 

    override func layoutSubviews() { 
     mySubView.frame = self.bounds 
     super.layoutSubviews() 
    } 
} 

Nun sind die subview Grenzen ordnungsgemäß zu Beginn jedes Layout Pass eingestellt werden. Es ist eine billige Operation.

Auch die bounds Eigenschaft eines UIView ist die frame in den Raum internen Koordinaten Sicht übersetzt. Dies bedeutet, dass dies normalerweise gilt: bounds = CGRect(x: 0, y: 0, width: frame.size.width, height: frame.size.height). Ich schlage vor, die Dokumentation zum Layout der Ansicht zu lesen.

Alternativ können Sie das manuelle Layout vollständig entfernen und AutoLayout verwenden, um dies für Sie zu tun.

class SubView: UIImageView { 

    var mySubView: UIImageView 

    required init?(coder aDecoder: NSCoder) { 

     mySubView = UIImageView() 
     mySubView.backgroundColor = UIColor.cyan 

     super.init(coder: aDecoder) 
     self.addSubview(mySubView) 

     mySubView.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true 
     mySubView.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true 
     mySubView.widthAnchor.constraint(equalTo: widthAnchor).isActive = true 
     mySubView.heightAnchor.constraint(equalTo: heightAnchor).isActive = true 
    } 
} 
+0

Danke! Ich habe den Fall für meine Frage hier ein wenig vereinfacht - in meiner Bewerbung möchte ich keinen der Subviews in voller Größe, aber das Problem ist nur, dass ich eine fast pixelgenaue Feinsteuerung ihrer relativen Größen benötige. Ich habe versucht, AutoLayout für eine Weile zu benutzen, aber ich konnte es einfach nicht erreichen, um die Dinge so auszulegen, wie ich es brauchte, also dachte ich mir, dass ein manueller Ansatz mir Zeit sparen könnte. :) – rcca

+0

Was für Sie funktioniert Mann! Jede Situation ist anders. :) –

Verwandte Themen