2015-07-27 4 views
6

Also werde ich ein paar verschiedene abgerundete Tasten innerhalb einer App (bis hin zu runden Tasten) haben, und von was ich sagen kann, ist der einfachste Weg, dies zu erreichen, die CornerRadius-Eigenschaft der Tasten CALayer.Der beste Ort, um cornerRadius basierend auf UIButton Größe in Unterklasse zu setzen?

Allerdings möchte ich das nicht manuell für jede Schaltfläche machen, die es in jedem Controller erfordert, also dachte ich, eine einfache Unterklasse, die dies auf Init setzt, wäre der Weg.

Ich verwende Storyboard und Autolayout, um die Schaltflächen zu positionieren, zu skalieren und sie dieser Unterklasse zuzuweisen.

class RoundedButton: UIButton { 

    required init(coder aDecoder: NSCoder) { 
     super.init(coder: aDecoder) 
     self.layer.cornerRadius = self.bounds.size.height/2.0 
     self.clipsToBounds = true 
     NSLog("BUTTON BOUNDS: H-%f W-%f", self.bounds.size.height, self.bounds.size.width) 
     NSLog("BUTTON FRAME: H-%f W-%f", self.frame.height, self.frame.width) 
    } 
} 

Aber ich bin gekommen, an diesem Punkt (das heißt init), die Größe der weder den Rahmen noch Grenzen sind endgültig, um herauszufinden, dass. Für eine Schaltfläche im Storyboard-Format (und beschränkt) auf H40 x W40 zeigen die Grenzen/Rahmengrößen H30 x W38 an.

Das bedeutet, dass cornerRadius nicht den erwarteten Wert erhält.

Ich habe bestätigt, dass zu einem späteren Zeitpunkt (z. B. wenn die Schaltfläche bereits auf einen Tap reagieren kann), sein Rahmen/Grenzen tatsächlich H40 x W40 sind.

Nach all dem ist meine Frage innerhalb der Unterklasse UIButton, wann/wo kann ich cornerRadius sicher mit den endgültigen Rahmen/Grenzen Werte der Instanz setzen?

Antwort

16

Wenn Sie möchten, dass Ihr Code ausgeführt wird, nachdem die Ansicht AutoLayout durchlaufen hat, müssen Sie dies in layoutSubviews tun, nachdem Sie super.layoutSubviews() aufgerufen haben.

So:

class RoundedButton: UIButton { 

    override func layoutSubviews() { 
     super.layoutSubviews() 

     layer.cornerRadius = bounds.size.height/2.0 
     clipsToBounds = true 
    } 
} 

Dieser Code ist nicht perfekt aber, weil er nicht unterstützt, wenn Höhe größer als die Breite ist (leicht obwohl zu beheben ...).

+0

schreiben Da alle Antworten identisch sind und Sie kamen zuerst, ich werde Sie akzeptieren. Vielen Dank. Ich habe nicht wirklich erwähnt, dass der Grund, warum ich mich nur um die Höhe und nicht die Breite kümmere, weil ich weiß, dass alle meine Knöpfe entweder quadratisch oder horizontal rechteckig sind. Aber ja, eine allgemeinere Lösung würde nach der kleineren der beiden Dimensionen suchen. – RobertoCuba

1

Versuchen Sie dies in Button-Klasse.

override func layoutSubviews() { 
    super.layoutSubviews() 

    // here... 
} 
1

Da Sie wollen lieber verwenden initWithCoder als Initwithframe (wo man den Rahmen struct tun haben), können Sie die layoutSubviews Methode überschreiben. Wenn layoutSubviews aufgerufen wird, ist der Rahmen korrekt.

in Objective-C können Sie

- (void)layoutSubviews { 
    [super layoutSubviews]; 
    self.layer.cornerRadius = self.bounds.size.height/2; 

}