Continuiamo il nostro tour dell’UIkit framework analizzando oggi la classe UIButton.
Come sempre, la guida di riferimento è la Class Reference pubblicata da Apple® che potete trovare a questo indirizzo.
Analizzando la Class Reference, l’informazione principale, e non a caso Apple® la inserisce per prima, è l’albero “genealogico” della classe in questione, per esempio per la classe UIButton la reference dice:
inherits from UIControl : UIView : UIResponder : NSObject
quindi la gerarchia è questa:
Ho segnato in verde le classi che abbiamo già trattato su questo sito, in rosso la classe che trattiamo oggi.
Come è facile intuire, più ci spostiamo verso il basso nella gerarchia delle classi, più saranno i metodi e le proprietà utilizzabili sulla classe stessa, questo perché non solo dobbiamo considerare metodi e proprietà proprietari della classe, ma anche tutti quelli delle sue superclassi ereditati.
Credo che tutti sappiano trascinare un UIButton da Interface Builder, vediamo invece come aggiungerne uno alle nostre view a runtime
[UIButton * btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];btn.frame = CGRectMake(0, 0, 100, 50);
[btn setTitle:@"Hello, world!" forState:UIControlStateNormal];
[self.view addSubview:btn];
Esaminando il codice vediamo subito un particolare costruttore che prende in input un (UIButtonType)buttonType; questo può avere 6 possibili diversi valori ed il risultato è quello che si vede in questa immagine.
Nella prima riga non c’è un errore, il pulsante non si vede perché è un rettangolo trasparente. Questo tipo di pulsante può essere comodamente usato per ottenere un pulsante personalizzato, (se si chiama “custom” ci sarà un perché) infatti basterà inserire sotto il pulsante un controllo UIImageView di dimensioni e contenuto appropriato per ottenere un pulsante con qualsiasi immagine.
Per i fans di Interface Builder lo stesso risultato è ottenibile selezionando la voce corrente nel menù a discesa presente in “attributes inspector”:
Nell’istruzione successiva ne impostiamo la dimensione e posizione tramite la funzione CGRectMake già vista nell’articolo sulle UILabel.
Gli oggetti della classe derivate da UIControl possono trovarsi in diversi stati (anche più contemporaneamente). Gli stati possibili sono:
UIControlStateNormal | il controllo è attivo |
UIControlStateHighlighted | È lo stato “evidenziato” dei controlli. Un controllo si trova in questo stato quando viene toccato o quando viene trascinato. Possiamo verificare via codice se un controllo si trova in questo stato esaminando la sua proprietà ishighlighted |
UIControlStateDisabled | Il controllo è disabilitato. | UIControlStateSelected | Stato “selezionato”. per molti controlli non è disponibile. |
UIControlStateApplication | Riservato per scopi interni alla nostra applicazione. |
UIControlStateReserved | Riservato per scopi riservati del framework. |
Tutti i metodi che servono per modificare l’aspetto estetico dei controlli prendono quindi come parametro anche uno di questi valori. Sarà quindi possibile realizzare per esempio un pulsante rosso che diventa grigio quando viene disattivato e verde quando viene cliccato.
I metodi per modificare l’aspetto dei pulsanti sono:
- (void)setTitle:(NSString *)title forState:(UIControlState)state
- (void)setTitleColor:(UIColor *)color forState:(UIControlState)state
- (void)setTitleShadowColor:(UIColor *)color forState:(UIControlState)state
- (void)setImage:(UIImage *)image forState:(UIControlState)state
- (void)setBackgroundImage:(UIImage *)image forState:(UIControlState)state="objc"
Per ricevere in lettura questi valori sono previsti metodi analoghi:
- (NSString *)titleForState:(UIControlState)state
- (UIColor *)titleColorForState:(UIControlState)state
- (UIColor *)titleShadowColorForState:(UIControlState)state
- (UIImage *)imageForState:(UIControlState)state
- (UIImage *)backgroundImageForState:(UIControlState)state
Come se non bastasse sono state previste anche delle proprietà che quindi vengono usate con la sintassi nome_oggetto.nomeproprietà:
@property(nonatomic,readonly,retain) UILabel *titleLabel
@property(nonatomic, readonly, retain) NSString *currentTitle
@property(nonatomic, readonly, retain) UIColor *currentTitleColor
@property(nonatomic, readonly, retain) UIColor *currentTitleShadowColor
@property(nonatomic, readonly, retain) UIImage *currentImage
@property(nonatomic, readonly, retain) UIImage *currentBackgroundImage
Tutte queste personalizzazioni possono essere specificate anche tramite interface builder, ma se vogliamo modificare le proprietà di un controllo a runtime l’unica possibilità che abbiamo è quella di adoperare i metodi forniti da apple.
Vediamo qualche esempio di utilizzo di questi metodi:
//Creo un oggetto UIButton di tipo TypeRoundedRect
UIButton * btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
//lo posiziono al centro schermo.
btn.frame = CGRectMake(35, 215, 250, 50);
//ne imposto ìl titolo per lo stato normale.
[btn setTitle:@"STATO: NORMALE" forState:UIControlStateNormal];
//ne imposto il colore del titolo per lo stato normal.
[btn setTitleColor:[UIColor greenColor] forState:UIControlStateNormal];
//ne imposto il titolo per lo stato "cliccato"
[btn setTitle:@"STATO: CLICCATO" forState:UIControlStateHighlighted];
//ne imposto il colore del titolo per lo stato "cliccato"
[btn setTitleColor:[UIColor redColor] forState:UIControlStateHighlighted];
//accedo alla proprietà currentTitle
NSLog(@"IN QUESTO MOMENTO HA TITOLO: %@", btn.currentTitle);
//accedo al valore del titolo allo stato "cliccato."
NSLog(@"NELLO STATO ATTIVO HA TITOLO: %@",[btn titleForState:UIControlStateHighlighted]);
Prima di concludere vediamo due ultime “chicche”: la prima è la proprietà showsTouchWhenHighlighted, che determina se il pulsante deve illuminarsi quando viene cliccato. Basta quindi scrivere btn.showsTouchWhenHighlighted = YES un’ottima animazione sui nostri pulsanti.
Con la seconda ed ultima chicca vediamo la possibilità di assegnare, sempre a runtime, una funzione ad un determinato evento sul controllo (per i più smaliziati..una sorta di binding dinamico).
Il metodo è il seguente:
- (void)addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents
“target” è l’oggetto che deve rispondere all’evento..di solito si utilizza “self”
“action” è un selector, ne parleremo magari più avanti, per il momento basti dire che è il nome di un metodo dichiarato nella nostra classe.
“controlEvents” è l’evento che che deve essere riconosciuto.
nel nostro caso potremmo quindi scrivere
[btn addTarget:self action:@selector(aMethod:) forControlEvents:UIControlEventTouchDown];
@lla prossima 🙂
9 Responses to “UIButton – Guida completa all’uso”
5 Marzo 2010
Mokka77Altro articolo utile per chi è alle prime armi come me, grandi!! Una domanda, ma per personalizzare un pulsante, non possiamo sfruttare le proprietà image o background anziché mettere un uiimage sotto un uibutton trasparente?
5 Marzo 2010
ignazioccerto, non l’ho detto nell’articolo ma la proprietà image inserisce un’immagine al centro del pulsante, mentre la proprietà background mette un’immagine come sfondo.
io ho suggerito il trucco di mettere una uiimage perché di solito realizzo una immagine e “disegno” i pulsanti..e la metto come sfondo..si lo è un metodo grezzo.. ;(
11 Marzo 2010
andreaciao, complimenti, grandissimo tutorial…. k ne dite nel prossimo di un pickerview??
16 Febbraio 2011
RobertoCiao, volevo chiederti una cosa che non mi è chiara. ho realizzato un applicazione con un UIButton disegnato con interface builder. Ho legato il buttone all’evento come faccio normalmente, sempre da interface buiilder, e l’evento dovrebbe al “click” cambiarmi il titolo del bottone. con il metodo “setTitle” da te citato.
Non ottengo alcun errore di sintassi la funzione ho verificato che viene chiamata correttamente e il programma funziona senza andare in crash ma semplicemente non cambia il titolo del bottone.
come mai?
16 Febbraio 2011
ignaziocPer cambiare le proprietà di un UIButton disegnato tramite interface builder è necessario che nella classe tu abbia dichiarato un oggetto UIButton come IBOutlet
IBOutlet UIButton *mybutton;
Probabilmente questo già l’hai fatto, altrimenti il codice ti darebbe errori, ma l’hai anche associato tramite interface builder?
4 Agosto 2011
AndreaCiao, ho subclassato UINavigationBar per ottenere un background personalizzato. Adesso vorrei che i button della navbar nelle varie viste fossero coerenti col custom background. Come devo agire?
Avevo pensato a creare delle immagini statiche e assegnarle ai vari bottoni, ma questo avrebbe effetto solo sulle viste che ho creato personalmente e non sulle viste che richiamano determinati metodi (ad esempio email o address book). Grazie in anticipo.
5 Agosto 2011
AndreaIn sostanza dovrei sottoclassare il Rounded Rect per far sì che al posto di mantenere il colore di default assuma il colore del background customizzato della barra. Potete aiutarmi?
Grazie.
5 Agosto 2011
IgnaziocDovresti postare sul forum, qui ti leggiamo in pochi. Ma il roundrect button è un tipo di UIButton mentre tu parli di quelli che stanno nella barra di navigazione che sono diversi..
5 Agosto 2011
AndreaGrazie. Lo farò. 😉