Comment spécifier la taille pour l'image edge-to-edge personnalisée de l'iPhone 6/7?

Dites que je veux une image groupée pour prendre toute la largeur d'écran disponible dans une application iPhone – par exemple une bannière. Je my_banner.png avec largeur 320px , my_banner@2x.png avec largeur 640px et my_banner@3x.png pour iPhone 6 plus avec largeur 1242px . Mais la résolution de l' iPhone 6 est de 750×1334 pixels. Pourtant, il partage le suffixe @2x avec iPhone 4 et 5 qui ont 640px largeur de 640px .

Quelle est la méthode recommandée ou un bon moyen de spécifier un file image qui a été optimisé pour la largeur 750px de l' iPhone 6 ? On dirait que cela ne peut pas être fait dans un asset catalog ? Cela devrait-il être fait par programme? Y at-il un autre suffixe qui peut être utilisé pour l' iPhone 6 ?

Tailles d'écran iPhone 4,5,6 (Image extraite de http://www.iphoneresolution.com )

Il me semble que beaucoup de ces réponses veulent savoir comment contraindre l'imageView, où je pense que vous êtes préoccupé par le chargement du bon file multimédia? Je viendrais avec ma propre solution extensible future, quelque chose comme ceci:

"UIImage + DeviceSpecificMedia.h" – (une catégorie sur UIImage)

Interface:

 #import <UIKit/UIKit.h> typedef NS_ENUM(NSInteger, thisDeviceClass) { thisDeviceClass_iPhone, thisDeviceClass_iPhoneRetina, thisDeviceClass_iPhone5, thisDeviceClass_iPhone6, thisDeviceClass_iPhone6plus, // we can add new devices when we become aware of them thisDeviceClass_iPad, thisDeviceClass_iPadRetina, thisDeviceClass_unknown }; thisDeviceClass currentDeviceClass(); @interface UIImage (DeviceSpecificMedia) + (instancetype )imageForDeviceWithName:(NSSsortingng *)fileName; @end 

La mise en oeuvre:

 #import "UIImage+DeviceSpecificMedia.h" thisDeviceClass currentDeviceClass() { CGFloat greaterPixelDimension = (CGFloat) fmaxf(((float)[[UIScreen mainScreen]bounds].size.height), ((float)[[UIScreen mainScreen]bounds].size.width)); switch ((NSInteger)greaterPixelDimension) { case 480: return (( [[UIScreen mainScreen]scale] > 1.0) ? thisDeviceClass_iPhoneRetina : thisDeviceClass_iPhone ); break; case 568: return thisDeviceClass_iPhone5; break; case 667: return thisDeviceClass_iPhone6; break; case 736: return thisDeviceClass_iPhone6plus; break; case 1024: return (( [[UIScreen mainScreen]scale] > 1.0) ? thisDeviceClass_iPadRetina : thisDeviceClass_iPad ); break; default: return thisDeviceClass_unknown; break; } } @implementation UIImage (deviceSpecificMedia) + (NSSsortingng *)magicSuffixForDevice { switch (currentDeviceClass()) { case thisDeviceClass_iPhone: return @""; break; case thisDeviceClass_iPhoneRetina: return @"@2x"; break; case thisDeviceClass_iPhone5: return @"-568h@2x"; break; case thisDeviceClass_iPhone6: return @"-667h@2x"; //or some other arbitrary ssortingng.. break; case thisDeviceClass_iPhone6plus: return @"-736h@3x"; break; case thisDeviceClass_iPad: return @"~ipad"; break; case thisDeviceClass_iPadRetina: return @"~ipad@2x"; break; case thisDeviceClass_unknown: default: return @""; break; } } + (instancetype )imageForDeviceWithName:(NSSsortingng *)fileName { UIImage *result = nil; NSSsortingng *nameWithSuffix = [fileName ssortingngByAppendingSsortingng:[UIImage magicSuffixForDevice]]; result = [UIImage imageNamed:nameWithSuffix]; if (!result) { result = [UIImage imageNamed:fileName]; } return result; } @end 

J'utilise l'astuce suivante car certaines choses fonctionnent réellement:

  • Catalogue d'actifs pour des périphériques spécifiques
  • Spécifiez les images pour 1x , 2x sur la base de 320×640
  • Spécifiez les images pour 4 2x et 3x sur la base de 320×568 (iPhone 5)
  • Créez un nouveau jeu d'images pour l'iPhone 6 en particulier (car c'est le seul périphérique qui pose problème avec les bindings bord à bord)
  • Ne fournir que 2x image pour l'iPhone 6 en pleine résolution (750×1334)

Déclarer une constante

 #define IS_IPHONE_6 [[UIScreen mainScreen]nativeBounds].size.width == 750.0 ? true : false 

et l'utilise comme ceci:

 UIImage *image = [UIImage imageNamed:@"Default_Image_Name"]; if(IS_IPHONE_^) { image = [UIImage imageNamed:@"Iphone6_Image_Name"]; } 

Ce n'est peut-être pas la plus belle des solutions, mais cela fonctionne, du less tant que Apple ne fournit pas une meilleure API pour les bindings bord à bord.

Auto Layout est censé aider avec cette situation ..

Maintenant, dites-moi @Niklas Berglund que feriez-vous si l'appareil tourne? Disons que vous êtes en mode paysage maintenant .. Comment remplissez-vous l'espace horizontal qui n'est plus dans les actifs d'image?

Juste de la nourriture pour les pensées .. Mise en page automatique censé prendre soin de votre écran, peu importe quelle orientation, ou quel appareil vous exécutez votre application sur ..

Peut-être que Apple devrait commencer à cibler les orientations des appareils dans les actifs d'image à l'avenir?

Revenons à votre question. La solution consiste à replace vos images @ 2x par des images larges de 750px, puis de configurer Auto Layout. Oh oui, c'est la partie délicate ..

Si vous ajoutez juste des contraintes pour l'ajuster, il la comprimera horizontalement lorsqu'il sera affiché sur un écran de 4 ", mais vous pouvez utiliser des multiplicateurs pour resize l'image de manière appropriée. Voici comment vous pouvez le faire:

 [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[imageFooterView]|" options:0 mesortingcs:nil views:NSDictionaryOfVariableBindings(imageFooterView)]]; [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[imageFooterView]|" options:0 mesortingcs:nil views:NSDictionaryOfVariableBindings(imageFooterView)]]; float aspectRatio = imageFooterView.frame.size.height/imageFooterView.frame.size.width; [imageFooterView addConstraint:[NSLayoutConstraint constraintWithItem:imageFooterView atsortingbute:NSLayoutAtsortingbuteHeight relatedBy:NSLayoutRelationEqual toItem:imageFooterView atsortingbute:NSLayoutAtsortingbuteWidth multiplier:aspectRatio constant:0.0f]]; 

Je ne pouvais pas find un moyen de le faire non plus, car j'avais une image de fond qui était parfaitement dimensionnée avec le catalogue d'actifs sur tous les appareils sauf l'iPhone 6. Mon correctif (je l'ai fait dans SpriteKit)?

 if (bgNode.size.width != self.frame.size.width) { bgNode.texture = [SKTexture textureWithImageNamed:@"i6bg.png"]; [bgNode runAction:[SKAction scaleXTo:self.frame.size.width/bgNode.size.width y:self.frame.size.width/bgNode.size.height duration:.1]]; } 

bgNode est l'image d'arrière-plan tirée par l'appareil. Si c'est un iPhone 6, il ne correspondra pas à l'écran et donc la largeur de l'image d'arrière-plan ne sera pas la même que la largeur de l'écran. Lorsque l'appareil est reconnu comme un iPhone 6, je change la texture à la texture R4 (le @ 2x pour la rétine) et l'échelle aux dimensions correctes.

J'ai essayé de faire la même chose avec l'image @ 2x régulière, mais l'image mise à l'échelle semblait très mauvaise (elle était trop étirée et visible). Avec la texture R4 mise à l'échelle, les proportions de largeur / hauteur sont un peu mieux et donc le changement n'est même pas perceptible. J'espère que cela vous donne une idée de ce que vous pouvez faire avant qu'Apple ajoute un iPhone 6 Asset.

J'espère que cela permettra de résoudre tous vos problèmes liés à l'image bord à bord personnalisé.
Xcode 6 – xcassets pour un support d'image universel

Assurez-vous que si vous utilisez la layout automatique, vérifiez que la broche est sur zéro pour tous les bords et que les contraintes sur la marge ne sont pas cochées.

Vous pouvez également visiter ces liens pour les images de l'écran de lancement:
http://www.paintcodeapp.com/news/iphone-6-screens-demystified
http://www.paintcodeapp.com/news/ultimate-guide-to-iphone-resolutions

entrez la description de l'image ici

J'ai soulevé la même question au support technique Apple et ils confirment que pour l'image en plein écran, cela ne peut pas être fait dans le catalogue d'actifs: "Actuellement, il n'y a aucun moyen pour le catalogue d'actifs de charger des images spécifiques aux appareils. images spécifiques dont vous aurez besoin pour implémenter votre propre code pour détecter la taille de l'écran et choisir l'image appropriée.Vous pouvez déposer une request d'amélioration en utilisant le lien suivant: Assurez-vous d'expliquer votre cas d'utilisation pour cette fonctionnalité. "

J'ai vérifié la convention de dénomination d'une image de lancement générée à partir d'un catalogue d'actifs via Xcode 6 et la version paysage pour l'iPhone 6+, par exemple, avait: LaunchImage-Landscape-736h @ 3x .png

Basé sur cela, je suppose que ce serait comme suit, pour les appareils de la rétine, en supposant un file de base desert .png:

  • desert @ 2x : iPhone 4s (320 x 420)
  • desert-568h @ 2x : iPhones 5, 5C et 5S (320 x 568)
  • desert-667h @ 2x : iPhone 6 (375 x 667)
  • desert-736h @ 3x : iPhone 6+ (414 x 736)
  • desert @ 2x ~ ipad : iPad (1024 x 768)

Il n'y a pas de support natif pour ce cas, donc je pense qu'il vaudrait mieux le faire manuellement car travailler avec des noms de files non documentés peut facilement se casser dans le futur.

Mesurez simplement les dimensions de l'appareil et appelez l'image que vous voulez. c'est-à-dire le faire par programme

Donc, dans votre appdelegate avoir globals

 deviceHeight = self.window.frame.size.height; deviceWidth = self.window.frame.size.width; 

que vous pouvez appeler à plusieurs resockets. Ensuite, vérifiez-les et appelez l'image appropriée

 if (deviceWidth == 640){ image = IPHONE4IMAGE; deviceSsortingng = @"iPhone4"; } else... 

Dans mon cas, je voulais que ma sous-class controller de base ait la même image de fond que mon image de lancement.

NOTE: Cette approche ne fonctionnera pas à less que ce soit votre exigence spécifique.

En outre, même lorsque j'ai essayé de créer une image d'arrière-plan de taille correcte pour l'iPhone 6 (750×1334), charger cette image comme image de motif dans une couleur d'arrière-plan pour une vue a fini par augmenter l'image de manière indésirable.

Cette réponse m'a donné le code dont j'avais besoin pour find une bonne solution pour moi.

Voici le code que j'ai eu pour que mon image de lancement corresponde à l'image de UIViewController mon UIViewController (ou vice versa):

 - (void)viewDidLoad { [super viewDidLoad]; UIImage *background = [UIImage imageNamed:[self splashImageName]]; UIColor *backgroundColor = [UIColor colorWithPatternImage:background]; self.view.backgroundColor = backgroundColor; } - (NSSsortingng *)splashImageName { UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation]; CGSize viewSize = self.view.bounds.size; NSSsortingng *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 = CGSizeFromSsortingng(dict[@"UILaunchImageSize"]); if (CGSizeEqualToSize(imageSize, viewSize) && [viewOrientation isEqualToSsortingng:dict[@"UILaunchImageOrientation"]]) return dict[@"UILaunchImageName"]; } return nil; } 

Veuillez essayer cette class pour modifier le nom de l'image par programme.

 import UIKit class AGTools: NSObject { class func fullWidthImage(imageName: Ssortingng!) -> Ssortingng!{ let screenWidth = UIScreen.mainScreen().bounds.size.width switch (screenWidth){ case 320: // scale 2x or 1x return (UIScreen.mainScreen().scale > 1.0) ? "\(imageName)@2x" : imageName case 375: return "\(imageName)-375w@2x" case 414: return "\(imageName)-414w@3x" default: return imageName } } } 

utilisez cette méthode comme ça.

 _imgTest.image = UIImage(named: AGTools.fullWidthImage("imageName")) 

Tout d'abord, vous devez configurer votre imageView pour couvrir tout l'écran, Autolayout aidera beaucoup pour ce travail, jetez un coup d'oeil sur le lien ci-dessous et trouvez comment épingler les contraintes (Leading Space, Toping Space, Top Space et Bottom Space) en utilisant des Storyboards :

http://www.thinkandbuild.it/learn-to-love-auto-layout/

entrez la description de l'image ici

DEUXIÈME étape consiste à créer des jeux d'images spécifiques à l'appareil sur vos éléments d'image (image ci-dessous), pour afficher différentes images en fonction de l'appareil.

entrez la description de l'image ici

Découvrez cette infographie: http://www.paintcodeapp.com/news/ultimate-guide-to-iphone-resolutions

Il explique les différences entre les anciens iPhones, iPhone 6 et iPhone 6 Plus. Vous pouvez voir la comparaison des tailles d'écran en points, pixels rendus et pixels physiques

C'est tout

entrez la description de l'image ici

entrez la description de l'image ici

S'il vous plaît, donnez votre avis si vous avez des problèmes.