ios xcode ios7 xcode5 asset-catalog

ios - Xcode 5 & Catálogo de activos: ¿cómo hacer referencia a LaunchImage?



launch screen xcode (13)

Acabo de escribir un método general para obtener el nombre de la imagen splash para iPhone y iPad (Paisaje, Retrato), funcionó para mí, espero que te ayude también. Escribí esto con la ayuda de otras respuestas de SO, gracias @Pichirichi para toda la lista.

+(NSString*)getLaunchImageName { NSArray* images= @[@"LaunchImage.png", @"[email protected]",@"[email protected]",@"[email protected]",@"[email protected]",@"LaunchImage-700-Portrait@2x~ipad.png",@"LaunchImage-Portrait@2x~ipad.png",@"LaunchImage-700-Portrait~ipad.png",@"LaunchImage-Portrait~ipad.png",@"LaunchImage-Landscape@2x~ipad.png",@"LaunchImage-700-Landscape@2x~ipad.png",@"LaunchImage-Landscape~ipad.png",@"LaunchImage-700-Landscape~ipad.png"]; UIImage *splashImage; if ([self isDeviceiPhone]) { if ([self isDeviceiPhone4] && [self isDeviceRetina]) { splashImage = [UIImage imageNamed:images[1]]; if (splashImage.size.width!=0) return images[1]; else return images[2]; } else if ([self isDeviceiPhone5]) { splashImage = [UIImage imageNamed:images[1]]; if (splashImage.size.width!=0) return images[3]; else return images[4]; } else return images[0]; //Non-retina iPhone } else if ([[UIDevice currentDevice] orientation]==UIDeviceOrientationPortrait || [[UIDevice currentDevice] orientation] == UIDeviceOrientationPortraitUpsideDown)//iPad Portrait { if ([self isDeviceRetina]) { splashImage = [UIImage imageNamed:images[5]]; if (splashImage.size.width!=0) return images[5]; else return images[6]; } else { splashImage = [UIImage imageNamed:images[7]]; if (splashImage.size.width!=0) return images[7]; else return images[8]; } } else { if ([self isDeviceRetina]) { splashImage = [UIImage imageNamed:images[9]]; if (splashImage.size.width!=0) return images[9]; else return images[10]; } else { splashImage = [UIImage imageNamed:images[11]]; if (splashImage.size.width!=0) return images[11]; else return images[12]; } } }

Otros métodos de utilidad son

+(BOOL)isDeviceiPhone { if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) { return TRUE; } return FALSE; } +(BOOL)isDeviceiPhone4 { if ([[UIScreen mainScreen] bounds].size.height==480) return TRUE; return FALSE; } +(BOOL)isDeviceRetina { if ([[UIScreen mainScreen] respondsToSelector:@selector(displayLinkWithTarget:selector:)] && ([UIScreen mainScreen].scale == 2.0)) // Retina display { return TRUE; } else // non-Retina display { return FALSE; } } +(BOOL)isDeviceiPhone5 { if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone && [[UIScreen mainScreen] bounds].size.height>480) { return TRUE; } return FALSE; }

Estoy utilizando el catálogo de activos de Xcode 5, y me gustaría utilizar mi LaunchImage como imagen de fondo de mi vista de inicio (una práctica bastante común para hacer que la transición de ''cargar'' a ''cargada'' se vea sin problemas).

Me gustaría utilizar la misma entrada en el catálogo de activos para ahorrar espacio y no tener que replicar la imagen en dos conjuntos de imágenes diferentes.

Sin embargo, llamando:

UIImage *image = [UIImage imageNamed:@"LaunchImage"]; //returns nil


Aquí una categoría en UIImage basada en la solución proporcionada por Cherpak Evgeny más arriba.

UIImage + SplashImage.h :

#import <UIKit/UIKit.h> /** * Category on `UIImage` to access the splash image. **/ @interface UIImage (SplashImage) /** * Return the name of the splash image for a given orientation. * @param orientation The interface orientation. * @return The name of the splash image. **/ + (NSString *)si_splashImageNameForOrientation:(UIInterfaceOrientation)orientation; /** * Returns the splash image for a given orientation. * @param orientation The interface orientation. * @return The splash image. **/ + (UIImage*)si_splashImageForOrientation:(UIInterfaceOrientation)orientation; @end

UIImage + SplashImage.m :

#import "UIImage+SplashImage.h" @implementation UIImage (SplashImage) + (NSString *)si_splashImageNameForOrientation:(UIInterfaceOrientation)orientation { CGSize viewSize = [UIScreen mainScreen].bounds.size; NSString *viewOrientation = @"Portrait"; if (UIDeviceOrientationIsLandscape(orientation)) { viewSize = CGSizeMake(viewSize.height, viewSize.width); viewOrientation = @"Landscape"; } NSArray* imagesDict = [[[NSBundle mainBundle] infoDictionary] valueForKey:@"UILaunchImages"]; for (NSDictionary *dict in imagesDict) { CGSize imageSize = CGSizeFromString(dict[@"UILaunchImageSize"]); if (CGSizeEqualToSize(imageSize, viewSize) && [viewOrientation isEqualToString:dict[@"UILaunchImageOrientation"]]) return dict[@"UILaunchImageName"]; } return nil; } + (UIImage*)si_splashImageForOrientation:(UIInterfaceOrientation)orientation { NSString *imageName = [self si_splashImageNameForOrientation:orientation]; UIImage *image = [UIImage imageNamed:imageName]; return image; } @end


Con la ayuda de la respuesta de Pichirichi, implementé la siguiente categoría (iOS 7+): UIImage+AssetLaunchImage

En realidad, es poco más que generar un nombre sobre la marcha, pero probablemente será útil.


En la documentation se establece claramente:

"Cada conjunto en un catálogo de activos tiene un nombre . Puede usar ese nombre para cargar programáticamente cualquier imagen individual contenida en el conjunto. Para cargar una imagen, llame al método UIImage: ImageNamed: pasando el nombre del conjunto que contiene la imagen "

Usar la lista de Pichirichi ayuda a resolver esta incoherencia.


Esta es la lista (casi) completa de LaunchImage (sin incluir las imágenes del iPad sin barra de estado):


La respuesta de @ codeman actualizada para Swift 1.2:

func splashImageForOrientation(orientation: UIInterfaceOrientation, size: CGSize) -> String? { var viewSize = size var viewOrientation = "Portrait" if UIInterfaceOrientationIsLandscape(orientation) { viewSize = CGSizeMake(size.height, size.width) viewOrientation = "Landscape" } if let imagesDict = NSBundle.mainBundle().infoDictionary as? [String: AnyObject] { if let imagesArray = imagesDict["UILaunchImages"] as? [[String: String]] { for dict in imagesArray { if let sizeString = dict["UILaunchImageSize"], let imageOrientation = dict["UILaunchImageOrientation"] { let imageSize = CGSizeFromString(sizeString) if CGSizeEqualToSize(imageSize, viewSize) && viewOrientation == imageOrientation { if let imageName = dict["UILaunchImageName"] { return imageName } } } } } } return nil }

Para llamarlo, y para admitir la rotación para iOS 8:

override func viewWillAppear(animated: Bool) { if let img = splashImageForOrientation(UIApplication.sharedApplication().statusBarOrientation, size: self.view.bounds.size) { backgroundImage.image = UIImage(named: img) } } override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) { let orientation = size.height > size.width ? UIInterfaceOrientation.Portrait : UIInterfaceOrientation.LandscapeLeft if let img = splashImageForOrientation(orientation, size: size) { backgroundImage.image = UIImage(named: img) } }

Justo lo que necesitaba, ¡gracias!


Los LaunchImages son especiales y no son realmente un catálogo de activos en el dispositivo. Si mira usando iFunBox / iExplorer / etc (o en el simulador, o en el directorio de compilación) puede ver los nombres finales, y luego escribir el código para usarlos, por ej. para un proyecto solo de iPhone iOS7, esto configurará la imagen de inicio correcta:

NSString *launchImage; if ((UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) && ([UIScreen mainScreen].bounds.size.height > 480.0f)) { launchImage = @"LaunchImage-700-568h"; } else { launchImage = @"LaunchImage-700"; } [self.launchImageView setImage:[UIImage imageNamed:launchImage]];

Puse esto en viewDidLoad.

Esto no es realmente ideal, sería genial si Apple nos diera una buena API para hacer esto.


Me doy cuenta de que esta no es necesariamente la mejor solución para todos, pero la manera más fácil (y menos propensa a errores, en mi humilde opinión) de hacer esto es hacer una entrada por separado en el catálogo de Images.xcassets. Lo llamé SplashImage .

Cuando vaya a agregar una nueva entrada, asegúrese de no seleccionar "Nueva imagen de inicio" como una opción. En su lugar, seleccione el genérico "Nuevo conjunto de imágenes". A continuación, abra el inspector y seleccione las opciones relevantes. Si está compilando solo dispositivos Retina, como yo, puede seleccionar lo siguiente:

Esto le dejará cuatro entradas (iPhone 4S, iPhone 5 (s, c), iPhone 6 y iPhone 6 Plus).

Los archivos correspondientes a las imágenes son los siguientes:

| Resolution (Xcode entry) | Launch Image name | Device | |--------------------------|---------------------|------------------| | 1x | Default-750.png | iPhone 6 | | 2x | [email protected] | iPhone 4S | | Retina 4 2x | [email protected] | iPhone 5, 5s, 5c | | 3x | Default-1242.png | iPhone 6 Plus |

Por supuesto, después de haber hecho esto, simplemente puede usar [UIImage imageNamed:@"SplashImage"]


Mi aplicación actualmente solo es compatible con iOS 7 y versiones posteriores.

Así es como hago referencia a la imagen de lanzamiento desde el catálogo de activos:

NSDictionary *dict = @{@"320x480" : @"LaunchImage-700", @"320x568" : @"LaunchImage-700-568h", @"375x667" : @"LaunchImage-800-667h", @"414x736" : @"LaunchImage-800-Portrait-736h"}; NSString *key = [NSString stringWithFormat:@"%dx%d", (int)[UIScreen mainScreen].bounds.size.width, (int)[UIScreen mainScreen].bounds.size.height]; UIImage *launchImage = [UIImage imageNamed:dict[key]];

Puede agregar más pares de valores clave si desea admitir versiones anteriores de iOS.


Se puede acceder fácilmente a Lanzar imagen por una línea de código.

UIImage *myAppsLaunchImage = [UIImage launchImage];

Siga los pasos que se detallan a continuación para lograr la funcionalidad que se muestra arriba.

Paso 1. Amplíe la clase UIImage creando una categoría y agregue el siguiente método a ella.

+ (UIImage *)launchImage { NSDictionary *dOfLaunchImage = [NSDictionary dictionaryWithObjectsAndKeys: @"[email protected]",@"568,320,2,8,p", // ios 8 - iphone 5 - portrait @"[email protected]",@"568,320,2,8,l", // ios 8 - iphone 5 - landscape @"[email protected]",@"568,320,2,7,p", // ios 7 - iphone 5 - portrait @"[email protected]",@"568,320,2,7,l", // ios 7 - iphone 5 - landscape @"LaunchImage-700-Landscape@2x~ipad.png",@"1024,768,2,7,l", // ios 7 - ipad retina - landscape @"LaunchImage-700-Landscape~ipad.png",@"1024,768,1,7,l", // ios 7 - ipad regular - landscape @"LaunchImage-700-Portrait@2x~ipad.png",@"1024,768,2,7,p", // ios 7 - ipad retina - portrait @"LaunchImage-700-Portrait~ipad.png",@"1024,768,1,7,p", // ios 7 - ipad regular - portrait @"[email protected]",@"480,320,2,7,p", // ios 7 - iphone 4/4s retina - portrait @"[email protected]",@"480,320,2,7,l", // ios 7 - iphone 4/4s retina - landscape @"LaunchImage-Landscape@2x~ipad.png",@"1024,768,2,8,l", // ios 8 - ipad retina - landscape @"LaunchImage-Landscape~ipad.png",@"1024,768,1,8,l", // ios 8 - ipad regular - landscape @"LaunchImage-Portrait@2x~ipad.png",@"1024,768,2,8,p", // ios 8 - ipad retina - portrait @"LaunchImage-Portrait~ipad.png",@"1024,768,1,8,l", // ios 8 - ipad regular - portrait @"LaunchImage.png",@"480,320,1,7,p", // ios 6 - iphone 3g/3gs - portrait @"LaunchImage.png",@"480,320,1,7,l", // ios 6 - iphone 3g/3gs - landscape @"[email protected]",@"480,320,2,8,p", // ios 6,7,8 - iphone 4/4s - portrait @"[email protected]",@"480,320,2,8,l", // ios 6,7,8 - iphone 4/4s - landscape @"[email protected]",@"667,375,2,8,p", // ios 8 - iphone 6 - portrait @"[email protected]",@"667,375,2,8,l", // ios 8 - iphone 6 - landscape @"[email protected]",@"736,414,3,8,p", // ios 8 - iphone 6 plus - portrait @"[email protected]",@"736,414,3,8,l", // ios 8 - iphone 6 plus - landscape nil]; NSInteger width = ([UIScreen mainScreen].bounds.size.width>[UIScreen mainScreen].bounds.size.height)?[UIScreen mainScreen].bounds.size.width:[UIScreen mainScreen].bounds.size.height; NSInteger height = ([UIScreen mainScreen].bounds.size.width>[UIScreen mainScreen].bounds.size.height)?[UIScreen mainScreen].bounds.size.height:[UIScreen mainScreen].bounds.size.width; NSInteger os = [[[[[UIDevice currentDevice] systemVersion] componentsSeparatedByString:@"."] objectAtIndex:0] integerValue]; NSString *strOrientation = UIDeviceOrientationIsLandscape([[UIDevice currentDevice] orientation])?@"l":@"p"; NSString *strImageName = [NSString stringWithFormat:@"%li,%li,%li,%li,%@",width,height,(NSInteger)[UIScreen mainScreen].scale,os,strOrientation]; UIImage *imageToReturn = [UIImage imageNamed:[dOfLaunchImage valueForKey:strImageName]]; if([strOrientation isEqualToString:@"l"] && [strImageName rangeOfString:@"Landscape"].length==0) { imageToReturn = [UIImage rotate:imageToReturn orientation:UIImageOrientationRight]; } return imageToReturn; }

Paso 2. El método anterior debería funcionar agregando el siguiente código también en la misma categoría de UIImage

static inline double radians (double degrees) {return degrees * M_PI/180;} + (UIImage *)rotate:(UIImage*)src orientation:(UIImageOrientation) orientation { UIGraphicsBeginImageContext(src.size); CGContextRef context = UIGraphicsGetCurrentContext(); if (orientation == UIImageOrientationRight) { CGContextRotateCTM (context, radians(90)); } else if (orientation == UIImageOrientationLeft) { CGContextRotateCTM (context, radians(-90)); } else if (orientation == UIImageOrientationDown) { // NOTHING } else if (orientation == UIImageOrientationUp) { CGContextRotateCTM (context, radians(90)); } [src drawAtPoint:CGPointMake(0, 0)]; UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return image; }


Siguiendo la respuesta de @Pichirich, hice referencia a mi launchimage en InterfaceBuilder como:

"LaunchImage.png"

... y con Xcode 5.0.2, extrae automáticamente la imagen apropiada directamente del Catálogo de activos.

Esto es lo que esperaría, excepto por el movimiento desagradable de Apple de cambiar silenciosamente "Default.png" a "LaunchImage.png" :)


Versión rápida de la respuesta de Cherpak Evgeny:

func splashImageForOrientation(orientation: UIInterfaceOrientation) -> String { var viewSize = self.view.bounds.size var viewOrientation = "Portrait" if UIInterfaceOrientationIsLandscape(orientation) { viewSize = CGSizeMake(viewSize.height, viewSize.width) viewOrientation = "Landscape" } let imagesDict = NSBundle.mainBundle().infoDictionary as Dictionary<NSObject,AnyObject>! let imagesArray = imagesDict["UILaunchImages"] as NSArray for dict in imagesArray { let dictNSDict = dict as NSDictionary let imageSize = CGSizeFromString(dictNSDict["UILaunchImageSize"] as String) if CGSizeEqualToSize(imageSize, viewSize) && viewOrientation == (dictNSDict["UILaunchImageOrientation"] as String) { return dictNSDict["UILaunchImageName"] as String } } return "" }


- (NSString *)splashImageNameForOrientation:(UIInterfaceOrientation)orientation { CGSize viewSize = self.view.bounds.size; NSString* viewOrientation = @"Portrait"; if (UIDeviceOrientationIsLandscape(orientation)) { viewSize = CGSizeMake(viewSize.height, viewSize.width); viewOrientation = @"Landscape"; } NSArray* imagesDict = [[[NSBundle mainBundle] infoDictionary] valueForKey:@"UILaunchImages"]; for (NSDictionary* dict in imagesDict) { CGSize imageSize = CGSizeFromString(dict[@"UILaunchImageSize"]); if (CGSizeEqualToSize(imageSize, viewSize) && [viewOrientation isEqualToString:dict[@"UILaunchImageOrientation"]]) return dict[@"UILaunchImageName"]; } return nil; }