如何指定iPhone 6/7自定义边对边图像的大小?

时间:2014-09-17 13:39:04

标签: ios objective-c iphone cocoa-touch iphone-6

假设我想要一个捆绑的图像占用iPhone应用程序中所有可用的屏幕宽度 - 例如横幅。我创建my_banner.png宽度320pxmy_banner@2x.png宽度为640pxmy_banner@3x.png iPhone 6 plus ,宽度为{{ 1}}。但 iPhone 6 的分辨率为1242px像素。仍然与iPhone 4和5共享750×1334后缀,宽度为@2x

推荐方式好方法指定针对 iPhone 6的640px宽度进行了优化的图片文件 EM>?好像它不能在750px中完成?它应该以编程方式完成吗?是否有其他后缀可用于 iPhone 6

iPhone 4,5,6 screen sizes (从http://www.iphoneresolution.com提取的图像)

12 个答案:

答案 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)

我使用以下技巧,因为有些东西确实有用:

  • 特定设备的资产目录
  • 以320x640
  • 为基础指定1x2x的图片
  • 以320x568(iPhone 5)为基础指定4 2x3x的图片
  • 专门为iPhone 6创建一个新的图像集(因为这是唯一一个使边缘到边缘绑定出现问题的设备)
  • 仅以完整分辨率(750x1334)
  • 为iPhone 6提供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

enter image description here

答案 5 :(得分:1)

我向苹果技术支持提出了同样的问题,他们确认,对于全屏图像,它无法在资产目录中完成:&#34;目前,资产目录无法加载特定于设备的图像。如果您的应用需要支持特定于设备的图像,则需要实现自己的代码来检测屏幕大小并选择合适的图像。您可以使用以下链接提交增强请求。请务必解释此功能的用例。 &#34;

答案 6 :(得分:0)

我检查了通过Xcode 6从资产目录生成的启动图像的命名约定,例如,iPhone 6+的横向版本具有: LaunchImage-Landscape-736h @ 3x .png

基于此,我假设对于视网膜设备,假设基本文件沙漠 .png:

  • desert @ 2x :iPhone 4s(320 x 420)
  • desert-568h @ 2x :iPhone 5,5C和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)

答案 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)

首先 首先,您需要将imageView配置为覆盖所有屏幕, Autolayout 将对此工作有很大帮助,请查看下面的链接,找到如何使用故事板确定约束(前导空间,尾随空间,顶部空间和底部空间)

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

enter image description here

SECOND 步骤是在图片资源(下图)上创建特定于设备的图像集,以根据设备显示不同的图像。

enter image description here

查看此信息图: http://www.paintcodeapp.com/news/ultimate-guide-to-iphone-resolutions

它解释了旧款iPhone,iPhone 6和iPhone 6 Plus之间的差异。您可以看到点,渲染像素和物理像素的屏幕尺寸比较

这就是全部

enter image description here

enter image description here

如果您有任何问题,请提供反馈。