web-dev-qa-db-fra.com

iOS 7/Xcode 5: le périphérique d'accès lance les images par programme

Existe-t-il un moyen d'utiliser les applications LaunchImage en tant qu'arrière-plan d'une application iOS universelle sans placer les mêmes ressources d'image à plusieurs endroits?

Je ne pouvais pas accéder aux fichiers LaunchImage dans Images.xcassets, alors j'ai créé deux nouveaux ensembles d'images "Portrait en arrière-plan" et "Paysage en arrière-plan" (car il semble n'y avoir aucun moyen de mettre des images de paysage et de portrait dans le même ensemble).

Bien que cette solution de contournement fasse le travail, je détesterais inclure chaque image dans l'application deux fois. Cela a également un coût de maintenance élevé.

Tout conseil sur la façon d'accéder à LaunchImage pour le périphérique actuel est apprécié.

GCOLaunchImageTransition doit avoir effectué le travail pour iOS <7.

41
Timm

Vous pouvez copier/coller le code suivant pour charger l'image de lancement de votre application au moment de l'exécution:

// Load launch image
NSString *launchImageName;
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
{
    if ([UIScreen mainScreen].bounds.size.height == 480) launchImageName = @"[email protected]"; // iPhone 4/4s, 3.5 inch screen
    if ([UIScreen mainScreen].bounds.size.height == 568) launchImageName = @"[email protected]"; // iPhone 5/5s, 4.0 inch screen
    if ([UIScreen mainScreen].bounds.size.height == 667) launchImageName = @"[email protected]"; // iPhone 6, 4.7 inch screen
    if ([UIScreen mainScreen].bounds.size.height == 736) launchImageName = @"[email protected]"; // iPhone 6+, 5.5 inch screen
}
else if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
    if ([UIScreen mainScreen].scale == 1) launchImageName = @"LaunchImage-700-Portrait~ipad.png"; // iPad 2
    if ([UIScreen mainScreen].scale == 2) launchImageName = @"LaunchImage-700-Portrait@2x~ipad.png"; // Retina iPads
}
self.launchImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:launchImageName]];
55
John Erck

La plupart des réponses nécessitent de créer un nom d'image en fonction du type de périphérique, de l'échelle, de la taille, etc. Mais comme Matthew Burke l'a souligné, chaque image du catalogue d'images de lancement sera renommée "LaunchImage *" et nous pouvons donc effectuer une itération lors de notre lancement. images et recherchez l’image appropriée (pour le périphérique actuel). En Objective-C, cela pourrait ressembler à ceci:

NSArray *allPngImageNames = [[NSBundle mainBundle] pathsForResourcesOfType:@"png"
                                        inDirectory:nil];

for (NSString *imgName in allPngImageNames){
    // Find launch images
    if ([imgName containsString:@"LaunchImage"]){
        UIImage *img = [UIImage imageNamed:imgName];
        // Has image same scale and dimensions as our current device's screen?
        if (img.scale == [UIScreen mainScreen].scale && CGSizeEqualToSize(img.size, [UIScreen mainScreen].bounds.size)) {
            NSLog(@"Found launch image for current device %@", img.description);
            break;
        }
    }
}

(Veuillez noter que ce code utilise la méthode "containsString" introduite avec iOS 8. Pour les versions précédentes d'iOS, utilisez "rangeOfString")

40
Daniel Witurna

Ci-dessous, le résultat lorsque je teste sous iOS 7.0+, uniquement en orientation portrait:

3.5 inch screen: [email protected]
4.0 inch screen: [email protected]
4.7 inch screen: [email protected]
5.5 inch screen: [email protected]
iPad2          : LaunchImage-700-Portrait~ipad.png
Retina iPads   : LaunchImage-700-Portrait@2x~ipad.png
10
ZYiOS

Une version rapide de l'excellent answer de Daniel Witurna qui n'exige pas de vérification par rapport à une liste de tous les types d'appareils ou orientations connus.

func appLaunchImage() -> UIImage?
{
    let allPngImageNames = NSBundle.mainBundle().pathsForResourcesOfType("png", inDirectory: nil)

    for imageName in allPngImageNames
    {
        guard imageName.containsString("LaunchImage") else { continue }

        guard let image = UIImage(named: imageName) else { continue }

        // if the image has the same scale AND dimensions as the current device's screen...

        if (image.scale == UIScreen.mainScreen().scale) && (CGSizeEqualToSize(image.size, UIScreen.mainScreen().bounds.size))
        {
            return image
        }
    }

    return nil
}
9
Simo

Info.plist in bundle contient les informations sur l'image de lancement, y compris le nom de l'image de lancement.

Objectif c:

- (UIImage *)getCurrentLaunchImage {
    CGSize screenSize = [UIScreen mainScreen].bounds.size;

    NSString *interfaceOrientation = nil;
    if (([[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationPortraitUpsideDown) ||
        ([[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationPortrait)) {
        interfaceOrientation = @"Portrait";
    } else {
        interfaceOrientation = @"Landscape";
    }

    NSString *launchImageName = nil;

    NSArray *launchImages = [[[NSBundle mainBundle] infoDictionary] valueForKey:@"UILaunchImages"];
    for (NSDictionary *launchImage in launchImages) {
        CGSize launchImageSize = CGSizeFromString(launchImage[@"UILaunchImageSize"]);
        NSString *launchImageOrientation = launchImage[@"UILaunchImageOrientation"];

        if (CGSizeEqualToSize(launchImageSize, screenSize) &&
            [launchImageOrientation isEqualToString:interfaceOrientation]) {
            launchImageName = launchImage[@"UILaunchImageName"];
            break;
        }
    }

    return [UIImage imageNamed:launchImageName];
}

Swift 4:

func getCurrentLaunchImage() -> UIImage? {

    guard let launchImages = Bundle.main.infoDictionary?["UILaunchImages"] as? [[String: Any]] else { return nil }

    let screenSize = UIScreen.main.bounds.size

    var interfaceOrientation: String
    switch UIApplication.shared.statusBarOrientation {
    case .portrait,
         .portraitUpsideDown:
        interfaceOrientation = "Portrait"
    default:
        interfaceOrientation = "Landscape"
    }

    for launchImage in launchImages {

        guard let imageSize = launchImage["UILaunchImageSize"] as? String else { continue }
        let launchImageSize = CGSizeFromString(imageSize)

        guard let launchImageOrientation = launchImage["UILaunchImageOrientation"] as? String else { continue }

        if
            launchImageSize.equalTo(screenSize),
            launchImageOrientation == interfaceOrientation,
            let launchImageName = launchImage["UILaunchImageName"] as? String {
            return UIImage(named: launchImageName)
        }
    }

    return nil
}
4
Lavare

Une fonction concise dans Swift pour obtenir le nom de l'image de lancement au moment de l'exécution:

func launchImageName() -> String {
    switch (UI_USER_INTERFACE_IDIOM(), UIScreen.mainScreen().scale, UIScreen.mainScreen().bounds.size.height) {
        case (.Phone, _, 480): return "[email protected]"
        case (.Phone, _, 568): return "[email protected]"
        case (.Phone, _, 667): return "[email protected]"
        case (.Phone, _, 736): return "[email protected]"
        case (.Pad, 1, _): return "LaunchImage-700-Portrait~ipad.png"
        case (.Pad, 2, _): return "LaunchImage-700-Portrait@2x~ipad.png"
        default: return "LaunchImage"
    }
}
2
Jason Cabot

La réponse de Matthew Burke est la bonne réponse. Vous trouverez ci-dessous le code que j'utilise pour que cela fonctionne pour iOS9/Xcode7, permettant de créer une application pour iOS7 ou ultérieure, pour iPhone et iPad, en mode paysage.

Tout d’abord, pour en dire un peu plus: Dans iOS8/Xcode6, si vous utilisiez un fichier d’écran de lancement de storyboard, au démarrage de l’application, l’application créerait 2 images (un portrait, un paysage) de résolution correcte pour votre appareil et vous avez pu obtenir cette image à partir du chemin du fichier. (Je crois qu'il a été stocké dans le dossier Library/LaunchImage). 

Cependant, dans iOS9/XCode 7, cette image n'est plus créée (bien qu'un instantané soit pris dans le dossier des instantanés, mais qu'il porte un nom non descriptif qui change tout le temps), donc si vous souhaitez utiliser votre LaunchImage ailleurs dans votre code, vous devrez utiliser une source d'image de lancement (via le catalogue d'actifs, de préférence, en raison de l'application Thinning). Maintenant, comme l'explique Matthew Burke, vous ne pouvez pas obtenir cette image simplement en faisant:

let launchImage = UIImage(named: "LaunchImage")

Même si le nom de l'image dans votre catalogue d'actifs est LaunchImage, Xcode/iOS9 ne vous le permettra pas.

Heureusement, vous n'avez pas besoin d'inclure à nouveau vos images de lancement dans votre catalogue d'actifs. Heureusement, cela signifie une augmentation de 20 Mo de la taille de téléchargement de votre application si vous créez une application pour tous les appareils. 

Alors, comment se rendre à ces images de lancement que? Eh bien, voici les étapes:

  1. Créez vos images de lancement et mettez-les dans votre catalogue d'actifs. Le nom des images n'est pas important.
  2. Assurez-vous que votre fichier d'écran de lancement (sous les paramètres généraux de votre cible) est vide et supprimez votre application de votre appareil et de votre simulateur. (supprimer simplement le nom de fichier et le ré-exécuter ne le fera pas, vous devrez d'abord supprimer votre application)
  3. Exécutez votre application dans le simulateur et accédez au dossier ~/Bibliothèque/Application Support/iPhone Simulator pour y trouver votre application. (C'est un peu fastidieux, car les noms des dossiers sont indescriptifs.) Affichez le contenu du paquet pour votre fichier .app et vous y verrez plusieurs fichiers image commençant par "LaunchImage- ...". Dans mon cas, il y avait 9 images. alors que je crée une application pour iPhone et iPad pour iOS7 et plus.
  4. Ensuite, dans votre code, vous devrez déterminer le périphérique sur lequel votre application s'exécute et s'il est en mode portrait ou paysage, puis décider de l'image à utiliser. Pour rendre cela un peu plus facile, j'ai utilisé ce cadre: https://github.com/InderKumarRathore/DeviceGuru . Attention, il ne contient pas encore les derniers appareils (iPhone 6s et iPhone 6s plus), vous devez donc ajouter une ligne dans son fichier Swift pour cela. Ensuite, placez le morceau de code ci-dessous dans le vc où vous voulez que votre launchImage et voilà:

    func launchImage() -> UIImage? {
        if let launchImageName = launcheImageName() {
            print(launchImageName)
            return UIImage(named: launchImageName)
        }
        else {
            print("no launch image")
            return nil
        }
    }
    
    func launcheImageName() -> String? {
        let HD35 = "[email protected]"
        let HD40 = "LaunchImage-700-568h@2x"
        let HD47 = "[email protected]"
        var HD55 = "[email protected]"
        var padHD = "LaunchImage-700-Portrait@2x~ipad.png"
        var pad = "LaunchImage-700-Portrait~ipad.png"
    
        if UIDevice.currentDevice().orientation == UIDeviceOrientation.LandscapeLeft || UIDevice.currentDevice().orientation == UIDeviceOrientation.LandscapeRight {
            HD55 = "[email protected]"
            padHD = "LaunchImage-700-Landscape@2x~ipad.png"
            pad = "LaunchImage-700-Landscape~ipad.png"
        }
    
        let hardware = hardwareString()
        if (hardware == "iPhone1,1")            { return HD35 }
        if (hardware == "iPhone1,2")            { return HD35 }
        if (hardware == "iPhone2,1")            { return HD35 }
        if (hardware == "iPhone3,1")            { return HD35 }
        if (hardware == "iPhone3,2")            { return HD35 }
        if (hardware == "iPhone3,3")            { return HD35 }
        if (hardware == "iPhone4,1")            { return HD35 }
        if (hardware == "iPhone5,1")            { return HD40 }
        if (hardware == "iPhone5,2")            { return HD40 }
        if (hardware == "iPhone5,3")            { return HD40 }
        if (hardware == "iPhone5,4")            { return HD40 }
        if (hardware == "iPhone6,1")            { return HD40 }
        if (hardware == "iPhone6,2")            { return HD40 }
        if (hardware == "iPhone7,1")            { return HD55 }
        if (hardware == "iPhone7,2")            { return HD47 }
        if (hardware == "iPhone8,1")            { return HD55 }
        if (hardware == "iPhone8,2")            { return HD47 }
    
        if (hardware == "iPod1,1")              { return HD35 }
        if (hardware == "iPod2,1")              { return HD35 }
        if (hardware == "iPod3,1")              { return HD35 }
        if (hardware == "iPod4,1")              { return HD35 }
        if (hardware == "iPod5,1")              { return HD40 }
    
        if (hardware == "iPad1,1")              { return pad }
        if (hardware == "iPad1,2")              { return pad }
        if (hardware == "iPad2,1")              { return pad }
        if (hardware == "iPad2,2")              { return pad }
        if (hardware == "iPad2,3")              { return pad }
        if (hardware == "iPad2,4")              { return pad }
        if (hardware == "iPad2,5")              { return pad }
        if (hardware == "iPad2,6")              { return pad }
        if (hardware == "iPad2,7")              { return pad }
        if (hardware == "iPad3,1")              { return padHD }
        if (hardware == "iPad3,2")              { return padHD }
        if (hardware == "iPad3,3")              { return padHD }
        if (hardware == "iPad3,4")              { return padHD }
        if (hardware == "iPad3,5")              { return padHD }
        if (hardware == "iPad3,6")              { return padHD }
        if (hardware == "iPad4,1")              { return padHD }
        if (hardware == "iPad4,2")              { return padHD }
        if (hardware == "iPad4,3")              { return padHD }
        if (hardware == "iPad4,4")              { return padHD }
        if (hardware == "iPad4,5")              { return padHD }
        if (hardware == "iPad4,6")              { return padHD }
        if (hardware == "iPad4,7")              { return padHD }
        if (hardware == "iPad4,8")              { return padHD }
        if (hardware == "iPad5,3")              { return padHD }
        if (hardware == "iPad5,4")              { return padHD }
    
        if (hardware == "i386")                 { return HD55 }
        if (hardware == "x86_64")               { return HD55 }
        if (hardware.hasPrefix("iPhone"))       { return HD55 }
        if (hardware.hasPrefix("iPod"))         { return HD55 }
        if (hardware.hasPrefix("iPad"))         { return padHD }
    
        //log message that your device is not present in the list
        logMessage(hardware)
    
        return nil
    }
    
1
guido

Voici le code modifié basé sur la solution de Daniel Witurna. Cet extrait de code utilise un prédicat pour filtrer le nom de l'image de lancement dans la liste des images de l'ensemble. Le prédicat évitera potentiellement le nombre de boucles pour filtrer l'image de lancement à partir d'un tableau de chemins d'image.

-(NSString *)getLaunchImageName{

NSArray *allPngImageNames = [[NSBundle mainBundle] pathsForResourcesOfType:@"png" inDirectory:nil];
NSString *expression=[NSString stringWithFormat:@"SELF contains '%@'",@"LaunchImage"];

NSArray *res = [allPngImageNames filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:expression]];

NSString *launchImageName;
for (launchImageName in res){
    {
        UIImage *img = [UIImage imageNamed:launchImageName];
        // Has image same scale and dimensions as our current device's screen?
        if (img.scale == [UIScreen mainScreen].scale && CGSizeEqualToSize(img.size, [UIScreen mainScreen].bounds.size)) {
            NSLog(@"Found launch image for current device %@", img.description);
            break;
        }

    }

}
return launchImageName; }
1
Saikiran K

Je ne sais pas si c'est ce que vous voulez dire par accès par code. Mais si vous sélectionnez votre "projet-> cible-> phases de construction-> copier les ressources du paquet", cliquez sur le '+' et "ajouter un autre", accédez à votre Images.xcassets-> LaunchImage.launchimage et sélectionnez le fichier png que vous souhaitez utiliser et cliquez sur "ouvrir". Maintenant, vous pouvez utiliser l'image comme [UIImage imageNamed:@"Default"];

1
Peter Segerblom
 if (IS_IPHONE_4_OR_LESS) {
    self.imageView.image = [UIImage imageNamed:@"[email protected]"];
}
else if (IS_IPHONE_5){
     self.imageView.image = [UIImage imageNamed:@"[email protected]"];
}
else if (IS_IPHONE_6){
     self.imageView.image = [UIImage imageNamed:@"[email protected]"];
}
else if (IS_IPHONE_6P){
      self.imageView.image = [UIImage imageNamed:@"[email protected]"];
}
1
shweta sharma

Si vous avez besoin de déterminer le périphérique, j'utilise le code suivant (c'est un peu rapide et sale, mais ça fait l'affaire)

if( UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone ){

    CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height;
    CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width;
    if( screenHeight < screenWidth ){
        screenHeight = screenWidth;
    }

    if( screenHeight > 480 && screenHeight < 667 ){
        DLog(@"iPhone 5/5s");
    } else if ( screenHeight > 480 && screenHeight < 736 ){
        DLog(@"iPhone 6");
    } else if ( screenHeight > 480 ){
        DLog(@"iPhone 6 Plus");
    } else {
        DLog(@"iPhone 4/4s");
    }
}
1
Roland Keesom

Une fois que vous avez créé le Images.xcassets, renommez simplement la LaunchImage en Default.

Cela évitera beaucoup de problèmes si vous prenez en charge iOS5 et iOS6.

Le nom actuel du "dossier"/de la catégorie suivra dans l'actif lors de la construction . Tout le reste est vrai, a déclaré Matthew Burke;)

0
Danoli3

Créez un nouveau groupe dans votre projet, sans aucun répertoire physique. Importez dans ce groupe vos images de lancement directement à partir de LaunchImage.launchimage. Voila.

0
QED