Articoli con Tag ‘Xcode’


Come localizzare immagini e viste di Interface Builder

Dopo aver illustrato come localizzare le nostre stringhe in Xcode, vediamo adesso quanto risulta semplice – applicando la medesima tecnica – localizzare immagini e viste/interfacce realizzate con Interface Builder.

Localizzare risorse grafiche

Il processo, come accennato, è il medesimo; se abbiamo un’immagine già inserita nelle nostre risorse, o ne inseriamo una nuova, e vogliamo “localizzarla” – cioè gestire due o più immagini in base alle lingue supportate – basterà cliccare con il tasto destro sull’immagine (Adium.png in questo esempio) e selezionare Get Info:

Clicchiamo Make File Localizable in basso a sinistra.

Clicchiamo su Add Localization e inseriamo Italian:

In modo da ottenere:

La nostra immagine viene spostata (fisicamente, una delle rare volte in cui quello che accade nell’alberatura Xcode si riflette sul filesystem) sotto le cartelle virtuali English.lproj e Italian.lproj esattamente come accadeva con il testo:

A questo punto ognuna delle cartelle English.lproj e Italian.lproj contiene una stessa versione dell’immagine. Questa immagine è manipolabile all’interno di Interface Builder, dove ne vedremo – per default – la versione inglese.
Arrivati a questo punto, basta sovrascrivere uno (o entrambi i file Adium.png) per ottenere una localizzazione delle immagini “lampo”.

Localizzare i file XIB

Anche le interfacce costruite con Interface Builder possono essere localizzate nella loro interezza, quando lo si ritiene necessario. Il procedimento è identico a quello svolto con le risorse grafiche: aggiungiamo un ViewController (ad esempio infoViewController) con interfaccia XIB, lo selezioniamo, scegliamo Get Info dal menu contestuale, rendiamo il file localizzabile, aggiungiamo la localizzazione in italiano:

ViewController

Cliccando su English o su Italian si aprirà Interface Builder! Questa volta, sul filesystem, noteremo che sono state create due cartelle (English.lproj e Italian.lproj) all’interno della classica cartella Classes. Entrambe avranno il loro file infoViewController.xib. La comodità, in questo, risolta evidente nel codice; quando andremo ad istanziare il nostro controller si avrà un codice “pulito” di questo tipo:

1
2
InfoViewController *info = [InfoViewController alloc];
[self.view addSubview:info.view];

Come vedete non c’è traccia di nessuna dichiarazione relativa alla localizzazione, totalmente gestita da sistema. Le due interfacce, ovviamente, possono essere completamente differenti, in quanto risultano a tutti gli effetti come due file XIB separati.

Continua...

10 utili trucchi e snippet per Apple iPhone e Xcode

1. Stringhe su più righe

In Xcode è possibile “spezzare” un stringa su più righe inserendo a alla fine un backslash “\”. Questa caratteristica può risultare utilissima quando, ad esempio, vogliamo inserire del testo HTML in un controllo UIWebView:

Continua...

Very short trick: 3 trick per gli sviluppatori Apple iPhone

Icona applicazione

L’icona 57×57 pixel che andrà a rappresentare la nostra applicazione viene “alterata” automaticamente dall’Apple iPhone: viene aggiunto un bordo arrotondato, un effetto luminoso e 3D. Questa impostazione può essere cambiata selezionando il file [nome applicazione]-Info.plist e aggiungendo la property “Icon already includes gloss and bevel effects”:

Continua...

XCode Objective-C: abbreviazioni utili da tastiera

XCode è davvero un ambiente di sviluppo potente e riserva sempre qualche sorpresa. Esso permette una funzione simile agli “snippet” del noto editor TextMate. In pratica è possibile inserire blocchi di codice utilizzando la sequenza tasto ESC + una combinazione di una o più sequenze di caratteri. Ad esempio se volete inserire un blocco if prova a premere ESC+if e otterrete:

Immagine 3

Come mostrato in figura, appare un menu (lo stesso del completamento automatico) dove è possibile scegliere tra un semplice blocco if o if/else. Cliccando “invio” si ottiene:

Immagine 4

Ecco due link utili per avere la lista completa delle combinazioni da tastiera:

Continua...

Objective-C: un’alternativa all’uso di CGRectMake

CGRectMake() è una funzione (in realtà è un inline #define) molto usata soprattutto quando si creano da codice oggetti grafici o di interfaccia utente. Il suo utilizzo è quindi spesso legato all’inizializzazione di componenti UIKit, ma anche a semplici UIView o UIImageView. CGRectMake() restituisce una struct (struttura di tipo) CGRect:

1
2
3
4
5
struct CGRect {
  CGPoint origin;
  CGSize size;
};
typedef struct CGRect CGRect;

Che a sua volta è composta da due diverse struct CGPoint e CGSize:

1
2
3
4
5
6
7
8
9
10
11
12
13
struct CGPoint {
  CGFloat x;
  CGFloat y;
};
typedef struct CGPoint CGPoint;

/* Sizes. */

struct CGSize {
  CGFloat width;
  CGFloat height;
};
typedef struct CGSize CGSize;

Che, a loro volta ancora, contengono tipi CGFloat, ovvero tipi float. Se andiamo ad analizzare il codice della CGRectMake() troviamo:

1
2
3
4
5
6
7
8
CG_INLINE CGRect
CGRectMake(CGFloat x, CGFloat y, CGFloat width, CGFloat height)
{
  CGRect rect;
  rect.origin.x = x; rect.origin.y = y;
  rect.size.width = width; rect.size.height = height;
  return rect;
}

Ne deriva, quindi, che questa parte di codice:

1
2
3
4
UIButton *gbutton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
gbutton.frame = CGRectMake (12,409,100,40);
[gbutton setTitle:@"Press" forState:UIControlStateNormal];
[mainWindow addSubview:gbutton];

Potrebbe, a ragione, essere scritta anche come:

1
2
3
4
UIButton *gbutton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
gbutton.frame = (CGRect) {12,409,100,40};
[gbutton setTitle:@"Press" forState:UIControlStateNormal];
[mainWindow addSubview:gbutton];

Giusto per velocizzare un po’ l’esecuzione del codice… :)

Continua...

Xcode shortcut

Xcode è davvero un ottimo ambiente di sviluppo, curato e denso di dettagli che rendono la scrittura di codice efficiente e piacevole. Tra questi c’è sicuramente la comodità del completamento automatico durante la digitazione, soprattutto quando si scrivono applicazioni per Apple iPhone, dove i framework sono tanti e ricordarsi sintassi e nomenclatura è impresa da pochi.

Continua...

XCode: consigli sul Debugging Preferences

Tramite le Preferences di Xcode è possibile impostare il comportamento dell’ambiente durante la fase di debugging di un’applicazione iPhone. Le impostazioni predefinite, infatti, sono assai scomode quando si prova e riprova un’applicazione; ad esempio, dopo aver lanciato la nostra applicazione, bisogna aprire manualmente la finestra Console per vedere l’output dei vari NSLog(). Inoltre Xcode lascia le precedenti sessioni così da costringerci a ripulire la finestra a mano. Fortunatamente è possibile risolvere il problema agendo sulle Preferences:

xcode-preferences

Come mostrato nella figura qui sopra, basta selezionare una delle voci del menu On Start per decide quale finestra di debug aprire in automatico all’avvio della nostra appicazione (io ho impostato Console & Debugger ma potete scegliere quelle che più vi fa comodo). Sulla destra poi troviamo Auto Clear Debug Console, così da partire sempre con la Console pulita.

Continua...

iPhone SecondApp: indovina il numero – parte 2

Come anticipato in iPhone FirstApp: indovina il numero – parte 1 vediamo come realizzare un’applicazione per Apple iPhone senza usare Interface Builder! Anzi, elimineremo fisicamente i file di Interface Builder creati dal wizard di Xcode. Alla fine di questo post, quindi, avremo un’applicazione identica, in tutto e per tutto, a quella realizzata nella parte prima, con la differenza che realizzeremo tutti i nostri componenti visivi, compresa la Window principale, completamente da codice.

L’applicazione già fatta, se volete solo scaricarla, è disponibile sul mio Google Code repository:

Vorrei far notare da subito come lo ZIP di questo esempio pesi meno di quello della scorsa volta! :)

Creiamo il progetto

Iniziamo creando il nostro progetto SecondApp (per distinguerlo da FirstApp), anche se questa volta sceglieremo Window-based Application:

newproject

Adesso andiamo ad eliminare tutto ciò che riguarda Interface Builder. Eliminiamo il file MainWindow.xib, situato nella cartella Resources: eliminatelo anche dal file system, quindi selezionate Also Move to Trash. Selezionate, poi, il file SecondoApp-info.plist ed eliminate il riferimento alla MainWindow nella casella Main nib file base name:

deleteib

A questo punto non abbiamo più nessuna Window, almeno tramite Interface Builder. Quindi apriamo il file main.m, situato in Other Sources, e modifichiamo la funzione main() in questo modo:

1
2
3
4
5
6
7
8
9
10
11
int main(int argc, char *argv[]) {
   
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
 
    // avendo eliminato il file .xib abbiamo perso il puntamento
    // all'app delegate, quindi lo passiamo a "mano"
    int retVal = UIApplicationMain(argc, argv, nil, @"SecondAppAppDelegate");

    [pool release];
    return retVal;
}

Apriamo quindi SecondAppAppDelegate.m e creiamo la Window principale via codice:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
- (void)applicationDidFinishLaunching:(UIApplication *)application {    

    // ottiene le dimensioni delle schermo (320, 480)
    CGRect windowRect = [[UIScreen mainScreen] applicationFrame];
    // creiamo una finestra - visto che abbiamo fatto bye bye a Interface Builder
    UIWindow *mainWindow = [[UIWindow alloc] initWithFrame:windowRect];
    // impostiamo il background della Window a giallo, per differenziarlo
    // dalla precedente applicazione FirstApp
    [mainWindow setBackgroundColor:[UIColor yellowColor]];
 
    [self setWindow:mainWindow];
    [window makeKeyAndVisible];
 
    [mainWindow release];
}

Potete già provare l’applicazione; se appare una window gialla avete fatto tutto bene!

Nel file SecondAppAppDelegate.h possiamo eliminare IBOutlet, necessario solo se si usa Interface Builder. Inoltre aggiungiamo qui le nostre variabili globali che, nella scorsa volta, avevamo inserito nel Controller. Modifichiamo quindi il file SecondAppAppDelegate.h:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#import <UIKit/UIKit.h>

@interface SecondAppAppDelegate : NSObject <UIApplicationDelegate> {
    UIWindow *window;
 
    UITextField *numero;
    UIButton *bottone;
    int numeroACaso;
}

@property (nonatomic, retain) UIWindow *window;

- (void)controllaNumero;

@end

Anche in questo caso abbiamo preparato la definizione del metodo controllaNumero, come la scorsa volta, ma abbiamo eliminato l’indicazione IBAction, in quanto non stiamo usando Interface Builder.

Costruiamo l’interfaccia da codice

E’ giunto il momento di creare tramite codice tutti i componenti della nostra interfaccia. Torniamo nel file SecondAppAppDelegate.m, posizioniamoci prima del [mainWindow release] ed inseriamo il seguente codice:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// crea la barra del titolo
UINavigationBar *myNavigationBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 44.0)];
myNavigationBar.barStyle = UIBarStyleDefault;
UINavigationItem *navigationItem = [[UINavigationItem alloc] initWithTitle:@"Indovina un numero"];
[myNavigationBar pushNavigationItem:navigationItem animated:NO];
[window addSubview:myNavigationBar];
 
// crea la label
UILabel *myLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 50, 300, 80)];
myLabel.backgroundColor = [UIColor clearColor];
myLabel.numberOfLines = 2;
myLabel.text = @"iPhone ha pensato un numero da 1 a 10, prova ad indovinarlo?";
[window addSubview:myLabel];
 
// crea il text input
numero = [[UITextField alloc] initWithFrame:CGRectMake(10, 120, 300, 30)];
numero.borderStyle = UITextBorderStyleRoundedRect;
numero.textAlignment = UITextAlignmentCenter;
numero.keyboardType = UIKeyboardTypeNumberPad;
numero.placeholder = @"Inserisci il numero";
[window addSubview:numero];
 
// crea il bottone
bottone = [UIButton buttonWithType:UIButtonTypeRoundedRect];
bottone.frame = CGRectMake(10, 180, 300, 30);
[bottone setTitle:@"Premi qui" forState:UIControlStateNormal];
[bottone addTarget:self action:@selector(controllaNumero) forControlEvents:UIControlEventTouchUpInside];
[window addSubview:bottone];
 
[myLabel release];
[navigationItem release];
[myNavigationBar release];

Dato che l’applicationDidFinishLaunching corrisponde alla viewDidLoad della scorsa volta, subito dopo il [mainWindow release]; inseriamo:

1
numeroACaso = 1 + arc4random() % 10;

Ora non ci rimane che implementare il metodo controllaNumero, che sarà identico (a parte il prototipo) a quello usato la scorsa volta:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
- (void) controllaNumero {
    NSLog(@"Premuto bottone di controlla numero");
    int numeroInserito = [numero.text integerValue];
    NSString *message;
    NSLog(@"Il numero inserito è %d", numeroInserito );
    if( numeroInserito <numeroACaso ) {
        message = @"Troppo basso...";
    } else if (numeroInserito> numeroACaso ) {
        message = @"Troppo alto...";
    } else if (numeroInserito == numeroACaso ) {
        message = @"Bravo hai indovinato";
        numeroACaso = 1 + arc4random() % 10;
        NSLog(@"Numero pensato %d", numeroACaso);
    }
    UIAlertView *alertMessaggio = [[UIAlertView alloc]
                initWithTitle:@"Responso"
                message: message
                delegate:nil
                cancelButtonTitle:@"OK"
                otherButtonTitles:nil];
    [alertMessaggio show];
    [alertMessaggio release];
    numero.text = @"";
}

Abbiamo finito!

Conclusioni e considerazioni

Questo esempio non fa uso diretto di una UIView o di un UIViewController, proprio perchè volevo lasciarlo il più semplice e snello possibile e, anche, per dimostrare che non sono elementi sempre necessari. Tuttavia inserire gli oggetti direttamente nella window può avere un qualche senso in questo esempio ed in altri sporadici contesti. L’uso delle UIView e dei UIViewController portano comunque benefici in tantissimi altri casi, ein alcuni sono praticamente indispensabili; come avremo modo di vedere in futuro.

Continua...

XCode: organizzare il codice con la direttiva #pragma mark

XCode è uno strumento davvero potente e versatile e fornisce al programmatore tantissime features utili e semplici da usare. Nella stesura di codice complesso, o quantomeno articolato, diventa importante organizzare il nostro codice in modo da non perdere tempo a cercare funzioni disseminate in lunghissime righe di codice. Oltre a commentare, prima e importante operazione da fare, l’ambiente XCode mette a disposizione delle direttive (simpatiche) per migliorare la legginilità e l’usabilità all’interno dell’ambiente di sviluppo. Una di queste è la direttiva #pragma mark che diventa utilissima nell’organizzare il codice e i gruppi di metodi.

Nell’immagine qui sotto è visibile la parte di codice del mio progetto PragmaTest:

pragmamark-1

Il menu dropdown in alto permette di elencare tutti i metodi della nostra classe. Ora se inseriamo sopra il nostro metodo la direttiva #pragma mark che ha una sintassi:

1
#pragma mark {label}

Otteniamo:

pragmamark-2

Il primo #pragma mark con il trattino (-) inserisce una riga di separazione. Il secondo è un testo (label) a piacere. Potete inserire la direttiva dove volete, organizzando il codice come meglio credete. Inoltre potete inserire anche più righe pragma, tipo:

1
2
3
4
5
6
#pragma mark -
#pragma mark /**
#pragma mark  * Uso della direttiva pragma
#pragma mark  * su più linee di codice
#pragma mark  */
- (void) mioMetodo {}

Continua...

XCode 3.1.3: ripristinare le SDK 2.2.1

Ai soli sviluppatori registrati è già stata rilasciata una nuova versione delle SDK per Apple iPhone, è quindi giunto il momento di installare le SDK 3.0 aggiornando così l’intero ambiente di sviluppo: XCode alla versione 3.1.3. Se avete già effettuato l’upgrade vi sarete accorti che creando un nuovo progetto sembrano scomparse le vecchie SDK 2.2.1 (comprese le altre).

xcode313

In realtà è tutto presente sulla nostra macchina, basta infatti eseguire una semplice procedura per ripristinare magicamente tutte le nostre SDK precedenti, così da provare la nostra applicazione per Apple iPhone sia con le SDK 3.0 che con le precedenti versioni 2.2.1 e minori. Selezionate il progetto, aprite il menu contestuale e selezionate Get Info:

xcode131menu

Nella finestra che si aprirà, nella prima scheda General, in basso selezionate Base SDK for All Configurations e ripristinate le SDK 2.2.1 (o quello che volete).

xcode313info

Fatto questo, magicamente, il menu di XCode rivisualizzerà tutte le SDK compresa la 3.0

xcode313ok

Continua...



Stop SOPA