Sviluppo e supporto App per iPhone 5

iPhone5 ha uno schermo più grande rispetto ai suoi precedessori. Gli sviluppatori di iOS6 devono supportare risoluzioni di 640 x 1136 px al posto di 640 x 960 px dell’iPhone4.
Ma anche in questo caso se si segue la logica Apple il lavoro da fare non è per nulla complicato.

Il blog http://blog.mugunthkumar.com/coding/supporting-the-iphone-5/ propone di seguire quattro fasi:

Fase 1:

iPhone 5 richiede un nuovo set di istruzioni, le armv7s. Solo nell’ultima versione Xcode ( 4.5) supporta la generazione del set istruzioni armv7s. Doa notare che, Xcode 4,5 non supporta più armv6 e depreca iPhone 3G e i dispositivi più vecchi. Quindi bisogna ora sviluppare le nostre applicazione utilizzando Xcode 4,5

Fase 2:

Il passo successivo è quello di aggiungere una immagine di lancio (Default-568h@2x.png). Quando si genera il progetto con Xcode 4.5, viene visualizzato un avviso, “Missing Retina 4 launch image”. Fare clic su “Aggiungi” per aggiungere un immagine di default al progetto.

Al lancio dell’ app apparirà in full screen on iPhone 5

Fase 3:

Tuttavia, la maggior parte dei nib file non sarà ancora in scalata correttamente. Il passo successivo è quello di controllare la maschera ridimensionamento automatico (auto resizing mask) di tutti i file nib e assicurarsi che la vista (view) all’interno del file nib si dimensioni automaticamente in base alla nuova altezza della vista.

Le proprietà che si usano sono:

UIViewAutoresizingFlexibleTopMargin,
UIViewAutoresizingFlexibleBottomMargin,
UIViewAutoresizingFlexibleHeight.

Si utilizza la UIViewAutoresizingFlexibleHeight per la visualizzazione on top in modo che auto dimensioni con la finestra principale. Si utilizza il UIViewAutoresizingFlexibleTopMargin e / o UIViewAutoresizingFlexibleBottomMargin per subviews.

UIViewAutoresizingFlexibleTopMargin viene utilizzato se si desidera che la visualizzazione secondaria eimanga “inchiodata” alla parte inferiore (il margine superiore è flessibile) e UIViewAutoresizingFlexibleBottomMargin viene utilizzato se si desidera che la visualizzazione secondaria sia “inchiodata” alla parte superiore (iò margine inferiore è flessibile).

Se invece si utilizza Cocoa auto Layout, questo passaggio diventa facoltativo. Tuttavia, l’auto Layout non è supportato su iOS 5.

Fase 4:

Infine, qualsiasi Layer che avete aggiunto alla vista dovrà essere ridimensionato manualmente. Il codice seguente mostra come eseguire questa operazione. Usiamo patternLayer per aggiungere un pattern per tutti i view controller. È necessario ridimensionare  nel metodo viewWillLayoutSubviews.

-(void)viewWillLayoutSubviews {

self.patternLayer.frame = self.view.bounds;
[super viewWillLayoutSubviews];
}Step 5 (if you were a messy coder):

 

Fase 5

Se l’altezza della view è stata codificato  a 460 o 480, potrebbe essere necessario cambiarle tutte  iinsrendo bounds. Ad esempio,

self.window = [[UIWindow alloc] initWithFrame: [[mainScreen UIScreen] bounds]];

invece di

self.window = [[UIWindow alloc] initWithFrame: CGRectMake (0, 0, 320, 480)];

 

Creare immagini con le nuove dimensioni

Come ho potuto constatare sul blog http://redth.info/get-your-monotouch-apps-ready-for-iphone-5-ios-6-today/ , purtroppo, la convenzione di denominazione di immagini-568h @ 2x.png sembra solo di essere utilizzata per l’immagine di default, ma non viene applicata per le altre immagini dell’ applicazione. Ciò significa che se si sta utilizzando un’immagine di sfondo personalizzata per la visualizzazione (ad esempio: UITableView background), è probabile che sia necessario creare una nuova immagine di sfondo alla risoluzione corretta, e determinare nell’applicazione quando utilizzare ciascuna immagine.
Sarebbe bello se Apple avesse esteso nel nuovo SDK il supporto al nuovo schermo per mezzo del metodo:
[UIImage imageNamed:@"my-image"]
Attualmente possiamo indicare per “my-image” il nome della mia immagine (anche senza estensione) e il sistema operativo effettua la ricerca dell’immagine nell’application bundle secondo questo criterio: se lo schermo è di tipo retina cerca un’immagine con il suffisso @2x nel nome, se non la trova va a cercare l’immagine senza suffisso. Ci saremmo aspettati da parte di Apple l’estensione dell’algoritmo includendo la possibilità di cercare per il suffisso -568h@2x nel caso di schermo da 4″. Purtroppo non è così e per questo motivo dovremo codificare la cosa espressamente nel nostro codice.

Per esempio, nella nostra app non-4inch  compatibile, ho due immagini:

Images / TableViewBackground.png – 320×358
Images / TableViewBackground@2x.png – 640×716

Con la nuova risoluzione, ho bisogno di creare una terza immagine (abbiamo deciso di utilizzare l’opzione-568h @ 2x.png convenzione di denominazione, anche se non è processata da Apple):

Images/TableViewBackground-568h@2x.png

Un approccio elegante è quello di creare una nuova categoria per la classe UIImage (che definiamo con poca fantasia UIImage+Retina4), e effettuare a runtime all’interno della categoria una sostituzione del metodo “imageNamed:” con uno che gestisca la nuova convenzione:


// all'interno di UIImage+Retina4.h
#import

@interface UIImage (Retina4)

@end

// all’interno di UIImage+Retina4.m
#import “UIImage+Retina4.h”
#ifdef TARGET_MAC_OS
#import
#else
#import
#endif

static Method origImageNamedMethod = nil;

@implementation UIImage (Retina4)

+ (void)initialize {
origImageNamedMethod = class_getClassMethod(self, @selector(imageNamed:));
method_exchangeImplementations(origImageNamedMethod,
class_getClassMethod(self, @selector(retina4ImageNamed:)));
}

+ (UIImage *)retina4ImageNamed:(NSString *)imageName {
NSMutableString *imageNameMutable = [imageName mutableCopy];
NSRange retinaAtSymbol = [imageName rangeOfString:@”@”];
if (retinaAtSymbol.location != NSNotFound) {
[imageNameMutable insertString:@”-568h” atIndex:retinaAtSymbol.location];
} else {
CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height;
if ([UIScreen mainScreen].scale == 2.f && screenHeight == 568.0f) {
NSRange dot = [imageName rangeOfString:@”.”];
if (dot.location != NSNotFound) {
[imageNameMutable insertString:@”-568h@2x” atIndex:dot.location];
} else {
[imageNameMutable appendString:@”-568h@2x”];
}
}
}
NSString *imagePath = [[NSBundle mainBundle] pathForResource:imageNameMutable ofType:@”png”];
if (imagePath) {
return [UIImage retina4ImageNamed:imageNameMutable];
} else {
return [UIImage retina4ImageNamed:imageName];
}
return nil;
}

@end

Quel che fa questo codice è in fase di inizializzazione sostituire l’implementazione di Apple di “imageNamed:” con la nostra “retina4ImageNamed:” (e viceversa). Nel momento stesso in cui il runtime chiama “imageNamed:” in realtà andrà a richiamare la nostra funzione che andrà a caricare l’immagine ottimizzata per lo schermo a 4″ a condizione che sia presente e che stiamo eseguendo l’app su un device con tale schermo (incluso il simulatore). Nel caso l’immagine non fosse presente o lo schermo fosse il tradizione 3.5″ allora verrebbe chiamata la funzione originale (rinominata a causa dello scambio iniziale).
Ovviamente questa implementazione non può essere usata nel caso il caricamento delle immagini avvenga esplicitamente per mezzo di chiamate del tipo
[UIImage imageWithContentsOfFile:...]
in cui il nome del file va costruito in maniera esplicita.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

*