假设我想要一个捆绑的图像占用iPhone应用程序中所有可用的屏幕宽度 - 例如横幅。我创建my_banner.png
宽度320px
,my_banner@2x.png
宽度为640px
,my_banner@3x.png
为 iPhone 6 plus ,宽度为{{ 1}}。但 iPhone 6 的分辨率为1242px
像素。仍然与iPhone 4和5共享750×1334
后缀,宽度为@2x
。
推荐方式或好方法指定针对 iPhone 6的640px
宽度进行了优化的图片文件 EM>?好像它不能在750px
中完成?它应该以编程方式完成吗?是否有其他后缀可用于 iPhone 6 ?
(从http://www.iphoneresolution.com提取的图像)
答案 0 :(得分:43)
在我看来,很多这些答案想要解决如何约束imageView,我认为你关心加载正确的媒体文件?我想出了我自己未来的可扩展解决方案,如下所示:
“UIImage + DeviceSpecificMedia.h” - (UIImage上的一个类别)
界面:
#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
实现:
#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
答案 1 :(得分:4)
我使用以下技巧,因为有些东西确实有用:
1x
,2x
的图片
4 2x
和3x
的图片2x
图像
声明一个常量
#define IS_IPHONE_6 [[UIScreen mainScreen]nativeBounds].size.width == 750.0 ? true : false
并像这样使用它:
UIImage *image = [UIImage imageNamed:@"Default_Image_Name"];
if(IS_IPHONE_^) {
image = [UIImage imageNamed:@"Iphone6_Image_Name"];
}
这可能不是最美丽的解决方案,但它起作用,至少只要apple没有为边缘到边缘绑定提供更好的API。
答案 2 :(得分:2)
自动布局应该有助于解决这种情况..
现在告诉我@Nicklas Berglund如果设备旋转你会怎么做?让我们说你现在处于横向模式..你将如何填充不再出现在图像资产中的水平空间?
只是思考的食物。无论是哪种方向,或者您正在运行应用程序的设备,自动布局都应该照顾您的屏幕。
也许Apple应该在未来开始定位图像资产中的设备方向?
让我们回到你的问题..解决方案是用750px宽的图像替换你的@ 2x图像,然后让自动布局完成它的工作。哦,是的,这是一个棘手的部分..
如果您只是添加约束以适应它,它会在4“屏幕显示时水平挤压它,但您可以使用乘数来适当缩放图像。以下是您可以这样做的方法:
[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]];
答案 3 :(得分:1)
我也找不到办法,因为我有一个背景图像,除了iPhone 6之外,每个设备上的资产目录都是完美的大小。我的修复(我在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是设备提取的背景图像。如果它是iPhone 6,它就不适合屏幕,因此背景图像宽度不会与屏幕宽度相同。当设备被识别为iPhone 6时,我将纹理更改为R4纹理(视网膜的@ 2x)并将其缩放到正确的尺寸。
我尝试使用常规的@ 2x图像做同样的事情,但缩放的图像看起来非常糟糕(它太过拉伸和显着)。随着R4纹理缩放,宽度/高度的比例更好一些,因此变化甚至不明显。我希望这可以让你了解在Apple添加iPhone 6资产之前你可以做些什么。
答案 4 :(得分:1)
希望这能解决与自定义边对边图像相关的所有问题 Xcode 6 - xcassets for universal image support
确保您使用的是自动布局,然后检查所有边缘的针脚是否为零,并且未检查边距约束。
您还可以访问此链接以获取启动屏幕图像:
http://www.paintcodeapp.com/news/iphone-6-screens-demystified
http://www.paintcodeapp.com/news/ultimate-guide-to-iphone-resolutions
答案 5 :(得分:1)
我向苹果技术支持提出了同样的问题,他们确认,对于全屏图像,它无法在资产目录中完成:&#34;目前,资产目录无法加载特定于设备的图像。如果您的应用需要支持特定于设备的图像,则需要实现自己的代码来检测屏幕大小并选择合适的图像。您可以使用以下链接提交增强请求。请务必解释此功能的用例。 &#34;
答案 6 :(得分:0)
我检查了通过Xcode 6从资产目录生成的启动图像的命名约定,例如,iPhone 6+的横向版本具有: LaunchImage-Landscape-736h @ 3x .png
基于此,我假设对于视网膜设备,假设基本文件沙漠 .png:
答案 7 :(得分:0)
本案例没有本地资产支持,所以我认为最好手动完成,因为使用未记录的文件名可能会在将来轻易破解。
答案 8 :(得分:0)
只需测量设备尺寸并调用所需的图像即可。即以编程方式进行。
所以在你的appdelegate中有全局
deviceHeight = self.window.frame.size.height;
deviceWidth = self.window.frame.size.width;
你可以反复打电话。 然后检查它们并调用适当的图像
if (deviceWidth == 640){
image = IPHONE4IMAGE;
deviceString = @"iPhone4";
}
else...
答案 9 :(得分:0)
就我而言,我有兴趣让我的基本视图控制器子类与我的启动图像具有相同的背景图像。
注意: 除非这是您的具体要求,否则此方法无效。
此外,即使我尝试为iPhone 6(750x1334)创建尺寸正确的背景图像,将该图像作为图案图像加载到视图的背景颜色最终也会以不合需要的方式缩放图像
This answer给了我代码,我需要为我找到一个好的解决方案。
这是我努力使我的发布图像与我的UIViewController
的背景图像匹配的代码(反之亦然):
- (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;
}
答案 10 :(得分:0)
请尝试使用此类以编程方式更改图像名称。
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
}
}
}
像这样使用这种方法。
_imgTest.image = UIImage(named: AGTools.fullWidthImage("imageName"))
答案 11 :(得分:-2)
http://www.thinkandbuild.it/learn-to-love-auto-layout/
SECOND 步骤是在图片资源(下图)上创建特定于设备的图像集,以根据设备显示不同的图像。
查看此信息图: http://www.paintcodeapp.com/news/ultimate-guide-to-iphone-resolutions
它解释了旧款iPhone,iPhone 6和iPhone 6 Plus之间的差异。您可以看到点,渲染像素和物理像素的屏幕尺寸比较
这就是全部
如果您有任何问题,请提供反馈。