2015-07-27 10 views
6

Quindi avrò alcuni pulsanti arrotondati diversi all'interno di un'app (fino ai pulsanti circolari), e da quello che posso dire, il modo più semplice per ottenere ciò è impostare la proprietà cornerRadius dei pulsanti CALayer.Il miglior posto per impostare cornerRadius basato sulla dimensione di UIButton nella sottoclasse?

Tuttavia, non voglio farlo manualmente per ogni pulsante che lo richiede in ogni controller, quindi ho pensato che una sottoclasse semplice che imposta questo su init sarebbe la strada.

Sto utilizzando Storyboard e Autolayout per posizionare e ridimensionare i pulsanti e assegnarli a questa sottoclasse.

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

ma sono venuto a scoprire che a questo punto (cioè init), la dimensione né il telaio né limiti sono finali. Per un pulsante in Storyboard dimensionato (e vincolato) su H40 x W40, le dimensioni dei bordi/frame mostrano H30 x W38.

Ciò significa che cornerRadius non ottiene il valore che mi aspetto.

Ho confermato che in un momento successivo (ad esempio quando il pulsante può già rispondere a un tocco) che i suoi frame/bound sono effettivamente H40 x W40.

Quindi, dopo tutto, la mia domanda è, all'interno della sottoclasse UIButton, quando/dove posso impostare in modo sicuro cornerRadius utilizzando i valori finali del frame/bound dell'istanza?

risposta

16

Se si desidera che il codice venga eseguito dopo che la vista è passata attraverso AutoLayout, è necessario farlo in layoutSubviews dopo aver chiamato super.layoutSubviews().

Ti piace questa:

class RoundedButton: UIButton { 

    override func layoutSubviews() { 
     super.layoutSubviews() 

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

Questo codice non è perfetto, però, perché non supporta quando l'altezza è più grande di larghezza (facile da risolvere però ...).

+0

Dal momento che tutte le risposte sono identiche e la vostra è venuto prima, io accetto la vostra. Grazie. In realtà non ho detto che il motivo per cui mi preoccupo solo dell'altezza e non della larghezza è perché so che tutti i miei pulsanti saranno quadrati o orizzontalmente rettangolari. Ma sì, una soluzione più generale cercherebbe la più piccola delle due dimensioni. – RobertoCuba

1

Prova questo in classe Button.

override func layoutSubviews() { 
    super.layoutSubviews() 

    // here... 
} 
1

Dal momento che si desidera utilizzare initWithCoder piuttosto che initWithFrame (dove si ha la struct telaio), è possibile eseguire l'override del metodo layoutSubviews. Quando si chiama layoutSubviews, il frame è corretto.

In Objective-C è possibile scrivere

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

} 
Problemi correlati