ios - fotos - ¿Cómo especificar el tamaño de la imagen personalizada de borde a borde del iPhone 6/7?
ios 12 (12)
En mi caso, estaba interesado en hacer que mi subclase de controlador de vista base tenga la misma imagen de fondo que mi imagen de inicio.
NOTA: Este enfoque no funcionará a menos que este sea su requisito específico.
Además, incluso cuando intenté crear una imagen de fondo que tenía el tamaño correcto para el iPhone 6 (750x1334), cargar esa imagen como imagen de patrón en un color de fondo para una vista terminó escalando la imagen de una manera indeseable.
Esta respuesta me dio el código que necesitaba para encontrar una buena solución para mí.
Aquí está el código que
UIViewController
para que mi imagen de inicio coincida con la imagen de fondo de mi
UIViewController
(o viceversa):
- (void)viewDidLoad {
[super viewDidLoad];
UIImage *background = [UIImage imageNamed:[self splashImageName]];
UIColor *backgroundColor = [UIColor colorWithPatternImage:background];
self.view.backgroundColor = backgroundColor;
}
- (NSString *)splashImageName {
UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
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;
}
Digamos que quiero que una imagen incluida ocupe todo el ancho de pantalla disponible en una aplicación de iPhone, por ejemplo, un banner.
my_banner.png
con ancho
320px
,
[email protected]
con ancho
640px
y
[email protected]
para
iPhone 6 plus
con ancho
1242px
.
Pero la resolución del
iPhone 6
es de
750×1334
píxeles.
Aún comparte el sufijo
@2x
con iPhone 4 y 5 que tienen
640px
ancho de
640px
.
¿Cuál es la
forma recomendada
o una
buena forma
de especificar un archivo de imagen que se haya optimizado para el ancho de
750px
del
iPhone 6
?
¿Parece que no se puede hacer en un
asset catalog
?
¿Debería hacerse programáticamente?
¿Hay algún otro sufijo que se pueda usar para
iPhone 6
?
(Imagen extraída de http://www.iphoneresolution.com )
Espero que esto resuelva todos sus problemas relacionados con la imagen personalizada de borde a borde.
Xcode 6 - xcassets para soporte de imagen universal
Asegúrese de que si está utilizando el diseño automático, el pin de verificación está establecido en cero para todos los bordes y las restricciones al margen no están marcadas.
También puede visitar estos enlaces para ver imágenes de la pantalla de inicio:
http://www.paintcodeapp.com/news/iphone-6-screens-demystified
http://www.paintcodeapp.com/news/ultimate-guide-to-iphone-resolutions
Estoy usando el siguiente truco ya que algunas cosas realmente funcionan:
- Catálogo de activos para dispositivos específicos
-
Especifique imágenes para
1x
,2x
en la base de 320x640 -
Especifique imágenes para
4 2x
y3x
en la base de 320x568 (iPhone 5) - Cree un nuevo conjunto de imágenes para el iPhone 6 específicamente (ya que este es el único dispositivo que causa problemas con los enlaces de borde a borde)
-
Solo proporcione
2x
imagen para iPhone 6 en resolución completa (750x1334)
Declarar una constante
#define IS_IPHONE_6 [[UIScreen mainScreen]nativeBounds].size.width == 750.0 ? true : false
y úsalo así:
UIImage *image = [UIImage imageNamed:@"Default_Image_Name"];
if(IS_IPHONE_^) {
image = [UIImage imageNamed:@"Iphone6_Image_Name"];
}
Esta podría no ser la solución más hermosa, pero funciona, al menos mientras Apple no proporcione una API mejor para los enlaces de borde a borde.
Le planteé la misma pregunta al soporte técnico de Apple y confirman que para la imagen a pantalla completa no se puede hacer en el catálogo de activos: "Actualmente, no hay forma de que el Catálogo de activos cargue imágenes específicas del dispositivo. Si su aplicación necesita ser compatible con el dispositivo imágenes específicas que necesitará para implementar su propio código para detectar el tamaño de la pantalla y elegir la imagen adecuada. Puede presentar una solicitud de mejora mediante el siguiente enlace. Asegúrese de explicar su caso de uso para esta función ".
Me parece que muchas de estas respuestas quieren abordar cómo restringir el imageView, donde creo que le preocupa cargar el archivo multimedia correcto. Se me ocurriría mi propia solución extensible futura, algo como esto:
"UIImage + DeviceSpecificMedia.h" - (una categoría en UIImage)
Interfaz:
#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:(NSString *)fileName;
@end
Implementación:
#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)
+ (NSString *)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 string..
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:(NSString *)fileName
{
UIImage *result = nil;
NSString *nameWithSuffix = [fileName stringByAppendingString:[UIImage magicSuffixForDevice]];
result = [UIImage imageNamed:nameWithSuffix];
if (!result) {
result = [UIImage imageNamed:fileName];
}
return result;
}
@end
No hay soporte nativo de activos para este caso, por lo que creo que sería mejor hacerlo manualmente, ya que trabajar con nombres de archivos no documentados puede romperse fácilmente en el futuro.
Por favor, intente esta clase para cambiar el nombre de la imagen mediante programación.
import UIKit
class AGTools: NSObject {
class func fullWidthImage(imageName: String!) -> String!{
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
}
}
}
usa este método así.
_imgTest.image = UIImage(named: AGTools.fullWidthImage("imageName"))
Se supone que el diseño automático ayuda con esta situación.
Ahora dime @Nicklas Berglund, ¿qué harías si el dispositivo gira? Digamos que está en modo horizontal ahora. ¿Cómo llenaría el espacio horizontal que ya no está en los activos de la imagen?
Solo alimento para los pensamientos. El diseño automático debe cuidar su pantalla sin importar la orientación o el dispositivo en el que esté ejecutando su aplicación.
¿Quizás Apple debería comenzar a orientar las orientaciones de dispositivos en activos de imagen en el futuro?
Volvamos a su pregunta. La solución es reemplazar sus imágenes @ 2x con imágenes de 750 px de ancho y luego hacer que Auto Layout haga su trabajo. Oh sí, esta es la parte difícil ...
Si solo agrega restricciones para ajustarlo, lo exprimirá horizontalmente cuando se muestre en una pantalla de 4 ", pero puede usar multiplicadores para escalar la imagen adecuadamente. Así es como puede hacerlo:
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[imageFooterView]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(imageFooterView)]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[imageFooterView]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(imageFooterView)]];
float aspectRatio = imageFooterView.frame.size.height/imageFooterView.frame.size.width;
[imageFooterView addConstraint:[NSLayoutConstraint constraintWithItem:imageFooterView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:imageFooterView attribute:NSLayoutAttributeWidth multiplier:aspectRatio constant:0.0f]];
Simplemente mida las dimensiones del dispositivo y llame a la imagen que desee. es decir, hacerlo programáticamente
Así que en tu applelegate tienes globals
deviceHeight = self.window.frame.size.height;
deviceWidth = self.window.frame.size.width;
que puedes llamar repetidamente. Luego verifíquelos y llame a la imagen apropiada
if (deviceWidth == 640){
image = IPHONE4IMAGE;
deviceString = @"iPhone4";
}
else...
Tampoco pude encontrar una manera de hacerlo, ya que tenía una imagen de fondo que tenía el tamaño perfecto con el Catálogo de activos en todos los dispositivos, excepto el iPhone 6. ¿Mi solución (hice esto en 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 es la imagen de fondo que el dispositivo extrae. Si se trata de un iPhone 6, no se ajustará a la pantalla y, por lo tanto, el ancho de la imagen de fondo no será el mismo que el ancho de la pantalla. Cuando el dispositivo se reconoce como un iPhone 6, cambio la textura a la textura R4 (el @ 2x para la retina) y la escalo a las dimensiones correctas.
Intenté hacer lo mismo con la imagen @ 2x normal, pero la imagen a escala se veía muy mal (estaba demasiado estirada y era notable). Con la textura R4 escalada, las proporciones de ancho / alto son un poco mejores y, por lo tanto, el cambio ni siquiera se nota. Espero que esto te dé una idea de lo que puedes hacer antes de que Apple agregue un iPhone 6 Asset.
Verifiqué la convención de nomenclatura de una imagen de lanzamiento generada a partir de un catálogo de activos a través de Xcode 6 y la versión horizontal para iPhone 6+, por ejemplo, tenía: LaunchImage-Landscape-736h @ 3x .png
Basado en eso, supongo que sería de la siguiente manera, para dispositivos de retina, suponiendo un archivo base desert .png:
- desierto @ 2x : iPhone 4s (320 x 420)
- desert-568h @ 2x : iPhones 5, 5C y 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)
En primer lugar, debe configurar su imageView para cubrir toda la pantalla, Autolayout ayudará mucho para este trabajo, eche un vistazo al siguiente enlace y descubra cómo anclar las restricciones (Espacio inicial, Espacio posterior, Espacio superior e Inferior) Espacio) usando Storyboards :
http://www.thinkandbuild.it/learn-to-love-auto-layout/
El SEGUNDO paso es crear conjuntos de imágenes específicas del dispositivo en sus activos de imagen (imagen a continuación), para mostrar diferentes imágenes según el dispositivo.
Vea esta infografía: http://www.paintcodeapp.com/news/ultimate-guide-to-iphone-resolutions
Explica las diferencias entre los antiguos iPhone, iPhone 6 y iPhone 6 Plus. Puede ver la comparación de tamaños de pantalla en puntos, píxeles renderizados y píxeles físicos
Eso es todo
Por favor, envíe un comentario si tiene algún problema.