wake-up-neo.com

iOS 7/Xcode 5: Zugriff auf das Gerät zum programmgesteuerten Starten von Bildern

Gibt es eine Möglichkeit, die Apps LaunchImage als Hintergrund in einer universellen iOS-App zu verwenden, ohne die gleichen Bildressourcen an mehreren Stellen zu platzieren?

Ich konnte nicht auf die LaunchImage-Dateien in Images.xcassets zugreifen. Daher erstellte ich zwei neue Bildsätze "Background Portrait" und "Background Landscape" (da es offensichtlich keine Möglichkeit gibt, Quer- und Hochformatbilder in den gleichen Satz zu bringen).

Während dieser Problemumgehung die Jobs erledigt, würde ich es hassen, jedes Bild zweimal in die App aufzunehmen. Dies hat auch einen hohen Wartungsaufwand zur Folge.

Alle Hinweise zum Zugriff auf LaunchImage für das aktuelle Gerät sind willkommen.

GCOLaunchImageTransition muss den Job für iOS <7 ausgeführt haben.

41
Timm

Sie können die Startbilder verwenden, ohne sie zweimal einfügen zu müssen. Der Schlüssel ist, dass bei Verwendung eines Asset-Katalogs die Dateinamen der Bilder, die im App-Paket enthalten sind, (standardisiert) standardisiert sind und möglicherweise nicht mit dem Namen der Originaldateien zusammenhängen.

Wenn Sie den Image-Satz LaunchImage verwenden, erhalten die Dateien, die im Anwendungspaket abgelegt werden, Namen wie

usw. Beachten Sie insbesondere, dass sie nicht Default.png oder irgendeine Variation davon genannt werden. Auch wenn Sie die Dateien so genannt haben. Sobald Sie sie in einem der wells im Asset-Katalog abgelegt haben, werden sie am anderen Ende mit einem Standardnamen ausgegeben.

[UIImage imageNamed:@"Default"] funktioniert daher nicht, da das App-Paket keine solche Datei enthält. [UIImage imageNamed:@"LaunchImage"] funktioniert jedoch (vorausgesetzt, Sie haben entweder das iPhone Portrait 2x gut oder das pre iOS7 iPhone Portrait 1x gut gefüllt).

Die Dokumentation gibt an, dass die imageNamed:-Methode für UIImage automatisch die richtige Version auswählen sollte, aber ich denke, dass dies nur für andere Image-Sets als das Start-Image gilt - zumindest habe ich nicht die richtige Funktion () nur ich mache etwas nicht richtig ).

Abhängig von Ihren genauen Umständen müssen Sie möglicherweise ein wenig ausprobieren, um den korrekten Dateinamen zu erhalten. Erstellen Sie die App und führen Sie sie im Simulator aus. Anschließend können Sie immer im entsprechenden Unterverzeichnis von ~/Library/Application Support/iPhone Simulator nach den tatsächlichen Dateinamen im App-Paket suchen.

Der wichtigste Punkt ist jedoch, dass keine Duplikate der Bilddateien enthalten sein müssen und Sie keine Anpassungen an der Copy Bundle Resources-Buildphase vornehmen müssen.

42
Matthew Burke

Sie können folgenden Code kopieren/einfügen, um das Startbild Ihrer App zur Laufzeit zu laden:

// 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 = @"[email protected]~ipad.png"; // Retina iPads
}
self.launchImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:launchImageName]];
55
John Erck

Für die meisten Antworten muss je nach Gerätetyp, Maßstab, Größe usw. ein Image-Name erstellt werden. Wie Matthew Burke jedoch darauf hinweist, wird jedes Image im Launch-Image-Katalog in "LaunchImage *" umbenannt. Daher können wir unseren Launch durchlaufen Bilder und finden Sie das (für das aktuelle Gerät) passende Bild. In Objective-C könnte es so aussehen:

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;
        }
    }
}

(Bitte beachten Sie, dass dieser Code die in iOS 8 eingeführte Methode "containsString" verwendet. Für frühere iOS-Versionen verwenden Sie "rangeOfString".)

40
Daniel Witurna

Wenn ich unter iOS 7.0+ teste, gilt nur das Hochformat:

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   : [email protected]~ipad.png
10
ZYiOS

Eine schnelle Version des ausgezeichneten answer von Daniel Witurna, bei dem keine Liste aller bekannten Gerätetypen oder Ausrichtungen geprüft werden muss.

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 im Bundle enthält Startbildinformationen, einschließlich des Namens des Startbildes.

Ziel 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];
}

Schnell 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

Eine kurze Funktion in Swift zum Abrufen des Startbildnamens zur Laufzeit:

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 "[email protected]~ipad.png"
        default: return "LaunchImage"
    }
}
2
Jason Cabot

Matthew Burkes Antwort ist die richtige Antwort. Im Folgenden finden Sie den Code, den ich verwende, um dieses Betriebssystem für iOS9/Xcode7 zum Laufen zu bringen, eine App für iOS7 und höher zu erstellen, für iPhone und iPad, die Landschaft erlaubt.

Um ein wenig mehr auszuarbeiten: Wenn Sie in iOS8/Xcode6 beim Start der App eine Storyboard-Startdatei verwenden, erstellt die App 2 Bilder (ein Portrait, eine Landschaft) dieser Startbildschirmdatei in der Richtige Auflösung für Ihr Gerät und Sie konnten dieses Bild vom Dateipfad abrufen. (Ich glaube, es wurde im Library/LaunchImage-Ordner gespeichert). 

In iOS9/XCode 7 wird dieses Bild jedoch nicht mehr erstellt (obwohl ein Snapshot im Ordner "Snapshots" erstellt wird, der jedoch einen sich ständig ändernden Namen hat). Wenn Sie also Ihr LaunchImage an anderer Stelle in Ihrem Code verwenden möchten, Sie müssen eine Launch Image Source verwenden (vorzugsweise durch den Asset-Katalog, da App Thinning verwendet wird). Matthew Burke erklärt, dass Sie dieses Bild nicht einfach erreichen können, indem Sie Folgendes tun:

let launchImage = UIImage(named: "LaunchImage")

Obwohl der Bildname in Ihrem Objektkatalog LaunchImage ist, können Sie Xcode/iOS9 nicht zulassen.

Glücklicherweise müssen Sie Ihre Startbilder nicht erneut in Ihren Asset-Katalog aufnehmen. Ich sage zum Glück, weil dies eine Steigerung der Größe des App-Downloads um 20 MB bedeuten würde, wenn Sie eine App für alle Geräte erstellen. 

Also, wie kommt man zu diesen Startbildern? Nun, hier sind die Schritte:

  1. Erstellen Sie Ihre Startbilder und legen Sie sie in Ihrem Objektkatalog ab. Der Name der Bilder ist nicht wichtig.
  2. Stellen Sie sicher, dass Ihre Startbilddatei (unter den allgemeinen Einstellungen Ihres Ziels) leer ist, und entfernen Sie Ihre App von Ihrem Gerät und Simulator. (Nur das Löschen des Dateinamens und das erneute Ausführen machen dies nicht, Sie müssen Ihre App zuerst entfernen.)
  3. Führen Sie Ihre App im Simulator aus, und navigieren Sie zum Ordner ~/Library/Application Support/iPhone Simulator. Dort finden Sie Ihre App. (Es ist etwas umständlich, da die Ordnernamen unbeschreiblich sind.) Zeigen Sie den Paketinhalt für Ihre .app-Datei. Dort werden mehrere Bilddateien angezeigt, die mit "LaunchImage- ..." beginnen. In meinem Fall gab es 9 Bilder Ich mache eine App für iPhone und iPad für iOS7 und höher.
  4. Anschließend müssen Sie in Ihrem Code ermitteln, auf welchem ​​Gerät Ihre App ausgeführt wird und ob es sich im Hoch- oder Querformat befindet, und dann entscheiden, welches Bild verwendet werden soll. Um dies ein wenig einfacher zu machen, habe ich dieses Framework verwendet: https://github.com/InderKumarRathore/DeviceGuru . Achtung, es wurden noch nicht die neuesten Geräte (iPhone 6s und iPhone 6s plus) mitgeliefert. Sie müssen dazu eine Zeile in seine Swift-Datei einfügen. Dann fügen Sie den Code in das VC-Verzeichnis ein, an dem Sie Ihr launchImage erstellen möchten.

    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 = "[email protected]"
        let HD47 = "[email protected]"
        var HD55 = "[email protected]"
        var padHD = "[email protected]~ipad.png"
        var pad = "LaunchImage-700-Portrait~ipad.png"
    
        if UIDevice.currentDevice().orientation == UIDeviceOrientation.LandscapeLeft || UIDevice.currentDevice().orientation == UIDeviceOrientation.LandscapeRight {
            HD55 = "[email protected]"
            padHD = "[email protected]~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

Hier ist der modifizierte Code basierend auf der Lösung von Daniel Witurna. Dieses Code-Snippet verwendet Prädikate, um den Startbildnamen aus der Liste der Bundle-Images zu filtern. Das Prädikat vermeidet möglicherweise die Anzahl der Schleifen, um das Startbild aus einem Array von Bildpfaden zu filtern.

-(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

Ich weiß nicht, ob Sie das mit Zugriff durch Code meinen. Wenn Sie jedoch "Projekt-> Ziel-> Bauphasen-> Ressourcen kopieren" klicken, klicken Sie auf "+" und "Weitere hinzufügen", navigieren Sie zu Images.xcassets-> LaunchImage.launchimage und wählen Sie die gewünschten Pngs aus und klicken Sie auf "Öffnen". Jetzt können Sie das Bild wie [UIImage imageNamed:@"Default"]; verwenden.

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

Wenn Sie das Gerät ermitteln müssen, verwende ich den folgenden Code (es ist ein bisschen schnell und schmutzig, aber es macht den Trick)

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

Eine weitere modernere und elegantere Lösung basiert auf ausgezeichnete Antwort von Daniel:

extension UIImage {
    static var launchImage: UIImage? {
        let pngs = Bundle.main.paths(forResourcesOfType: "png", inDirectory: nil)
        return pngs
            .filter({$0.contains("LaunchImage")})
            .compactMap({UIImage(named: $0)})
            .filter({$0.size == UIScreen.main.bounds.size})
            .first
    } 
}

Auf diese Weise können Sie einfach schreiben:

let myLaunchImage = UIImage.launchImage
0
apouche

Nachdem Sie den Images.xcassets erstellt haben, benennen Sie die LaunchImage einfach in Default um.

Dies erspart Ihnen viel Ärger, wenn Sie iOS5 und iOS6 unterstützen.

Der tatsächliche Name des "Ordners"/der Kategorie wird beim Erstellen in das Asset übernommen. Alles andere ist wahr, was Matthew Burke gesagt hat;)

0
Danoli3

Erstellen Sie in Ihrem Projekt eine neue Gruppe, die von keinem physischen Verzeichnis gesichert wird. Importieren Sie Ihre Startbilder direkt aus LaunchImage.launchimage in diese Gruppe. Voilá.

0
QED