2013-03-15 12 views
15

Ho una vista con un paio di pulsanti, varie dimensioni. Tutti loro hanno un titolo e un'immagine. Volevo avere l'immagine in alto, il titolo in fondo, centrato. Ciò funziona correttamente con il seguente codice:Impostazione UIButton titleEdgeInsets e imageEdgeInsets è lento con Autolayout

- (void)centerAlignImageAndTextForButton:(UIButton*)button 
{ 
    CGFloat spacing = 5; 
    CGSize imageSize = button.imageView.frame.size; 
    button.titleEdgeInsets = UIEdgeInsetsMake(0, -imageSize.width, -(imageSize.height + spacing), 0); 
    CGSize titleSize = button.titleLabel.frame.size; 
    button.imageEdgeInsets = UIEdgeInsetsMake(-(titleSize.height + spacing), 0, 0, -titleSize.width); 
} 

Tuttavia, noto una piccola pausa prima di entrare in questa visualizzazione. Tempo Profiler in Strumenti dimostra, che il 99% del tempo trascorso in viewDidLoad è causata chiamando il mio metodo per i pulsanti:

cose
283.0ms -[XViewController viewDidLoad] 
282.0ms -[XViewController centerAlignImageAndTextForButton:] 
141.0ms  -[UIButton imageView] 
98.0ms  -[UIView(Hierarchy) layoutBelowIfNeeded] 
141.0ms  -[UIButton titleLabel] 
103.0ms  -[UIView(Hierarchy) layoutBelowIfNeeded] 

Vari di layout relativi sono chiamati all'interno [UIView(Hierarchy) layoutBelowIfNeeded], come [UIView(AdditionalLayoutSupport) recursiveLayoutEngineDidChange] o [NSLayoutConstraint addToEngine].

So che sarebbe possibile impostare questi inserimenti in Interface Builder, ma non solo quello è un lavoro noioso (è necessario "indovinare" la larghezza del testo); l'app sarà anche localizzata, quindi gli insetti che sono validi per una lingua, non saranno per un'altra dove la dimensione del testo è diversa (sto usando la localizzazione di base per storyboard e file .strings invece di duplicare l'intero storyboard per ogni lingua). Quindi per me sembra che impostare gli insets a livello di codice sia la strada da percorrere, ma il ritardo che provoca non è realmente accettabile.

Qualche idea su come risolvere questo problema?

+0

Perché non li si imposta su 'layoutSubViews'? – orkoden

risposta

6

spostamento di tutte le chiamate da centerAlignImageAndTextForButtonviewDidLoad a viewDidLayoutSubviews riduce il tempo di caricamento dai precedenti 283 millisecs a 18 millisecs (1 millisecs per viewDidLoad e 17 millisecs per viewDidLayoutSubviews).

Tuttavia, io sono un po 'perplesso, perché è così costoso da impostare questi inserti da viewDidLoad ...

+1

Forse perché in viewDidLoad, nessuno dei tuoi layout è stato eseguito, quindi è necessario lavorare di più? In viewDidLayout ... la maggior parte del layout è già stata eseguita, quindi la regolazione degli inset è un tweak piuttosto che un layout completo. Questa è una supposizione. A proposito, se ti interessano gli inserti sui bordi nei pulsanti, di recente ho scritto su di essi (con un progetto di esempio) qui: http://commandshift.co.uk/blog/2013/03/12/uibutton-edge- insets/ – jrturton

+1

Sì, sono incappato in quel post mentre cercavo una soluzione. La tua ipotesi ha senso, mi è venuto in mente un pensiero simile quando ho trovato il metodo 'viewDidLayoutSubviews' nella documentazione, ecco perché l'ho provato (per fortuna). –

0

avuto un problema simile con una chiamata lento per titleLabel da awakeFromNib in costume UIButton sottoclasse. Spostare il codice per visualizzare il controller non era auspicabile a causa di un numero elevato e/o un ciclo di vita non banale dei pulsanti. Spostare il codice su layoutSubviews non ha aiutato. Alla fine ho spostato il codice su didMoveToSuperview e ho risolto il problema.

- (void)didMoveToSuperview 
{ 
    [super didMoveToSuperview]; 
    self.titleLabel.lineBreakMode = NSLineBreakByWordWrapping; 
    self.titleLabel.numberOfLines = 2; 
    self.titleLabel.textAlignment = NSTextAlignmentCenter; 
} 
Problemi correlati