Как указать размер для iPhone 6/7 для индивидуального изображения от края до края?

Скажем, я хочу, чтобы связанное изображение занимало всю ширину экрана в приложении iPhone - например, баннер. Я бы создал my_banner.png с шириной 320px, [email protected] с шириной 640px и [email protected] для iPhone 6 плюс с шириной 1242px. Но разрешение iPhone 6 составляет 750×1334 пикселей. Тем не менее он разделяет суффикс @2x с iPhone 4 и 5 с шириной 640px.

Какой рекомендуемый способ или хороший способ указать файл изображения, оптимизированный для ширины 750px для iPhone 6? Похоже, это невозможно сделать в asset catalog? Следует ли это делать программно? Есть ли еще какой-нибудь суффикс, который можно использовать для iPhone 6?

iPhone 4,5,6 screen sizes (Изображение извлечено из http://www.iphoneresolution.com)

Ответ 1

Мне кажется, что многие из этих ответов хотят решить, как ограничить изображениеView, где я думаю, что вы занимаетесь загрузкой правильного медиафайла? Я бы придумал свое будущее расширяемое решение, что-то вроде этого:

"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 @"[email protected]";
            break;
        case thisDeviceClass_iPhone6:
            return @"[email protected]"; //or some other arbitrary string..
            break;
        case thisDeviceClass_iPhone6plus:
            return @"[email protected]";
            break;

        case thisDeviceClass_iPad:
            return @"~ipad";
            break;
        case thisDeviceClass_iPadRetina:
            return @"[email protected]";
            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

Ответ 2

Я использую следующий трюк, поскольку некоторые вещи действительно работают:

  • Каталог активов для определенных устройств
  • Укажите изображения для 1x, 2x на основе 320x640
  • Укажите изображения для 4 2x и 3x на основе 320x568 (iPhone 5)
  • Создайте новый набор изображений для iPhone 6 (так как это единственное устройство, которое создает проблемы с привязкой к краям)
  • Предоставлять только 2x изображение для iPhone 6 в полном разрешении (750x1334)

Объявить константу

#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"];
}

это может быть не самое красивое решение, но оно работает, по крайней мере, до тех пор, пока яблоко не предоставляет лучшего API для привязки к краям.

Ответ 3

Предполагается, что Auto Layout поможет в этой ситуации.

Теперь скажите мне @Nicklas Berglund, что бы вы сделали, если устройство вращается? Допустим, теперь вы находитесь в ландшафтном режиме. Как бы вы заполнили горизонтальное пространство, которое больше не находится в изображениях?

Просто пища для мыслей. Автомакет, который должен заботиться о вашем экране, независимо от того, какую ориентацию или какое устройство вы используете для своего приложения.

Возможно, Apple должна начать ориентацию устройств на изображения в будущем?

Давайте вернемся к вашему вопросу.. Решение состоит в том, чтобы заменить ваши изображения @2x изображениями шириной 750 пикселей, а затем выполнить автоматическую компоновку. О да, это сложная часть.

Если вы просто добавите ограничения, чтобы соответствовать им, он будет сжимать его горизонтально, когда отображается на 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]];

Ответ 4

Я тоже не мог найти способ сделать это, так как у меня было фоновое изображение, которое было идеально размером с Каталогом ресурсов на каждом устройстве, кроме 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 Asset.

Ответ 5

Надеюсь, что это решит все ваши проблемы, связанные с настраиваемым краевым изображением. Xcode 6 - xcassets для универсальной поддержки изображений

Удостоверьтесь, что если вы используете автоматическую компоновку, тогда проверьте, что PIN-код установлен на ноль для всех краев, а ограничения для поля не отмечены.

Вы также можете посетить эти ссылки для изображений экрана запуска:
http://www.paintcodeapp.com/news/iphone-6-screens-demystified
http://www.paintcodeapp.com/news/ultimate-guide-to-iphone-resolutions

enter image description here

Ответ 6

Я поднял тот же вопрос к технической поддержке Apple, и они подтверждают, что для полноэкранного изображения это невозможно сделать в каталоге активов: "В настоящее время нет возможности для Каталога активов загружать изображения, специфичные для устройства. для поддержки изображений, специфичных для устройства, вам нужно будет реализовать свой собственный код, чтобы определить размер экрана и выбрать подходящее изображение. Вы можете подать запрос на повышение, используя следующую ссылку. Обязательно объясните свой вариант использования для этой функции."

Ответ 7

Я проверил соглашение об именах изображения запуска, сгенерированного из каталога активов, через Xcode 6, а ландшафтная версия для iPhone 6+, например, имела: LaunchImage-Landscape-736h @3x.png

Исходя из этого, я предполагаю, что для устройств сетчатки будет использоваться следующий файл пустыня.png:

  • пустыня @2x: iPhone 4s (320 x 420)
  • desert-568h @2x: iPhones 5, 5C и 5S (320 x 568)
  • desert-667h @2x: iPhone 6 (375 x 667)
  • desert-736h @3x: iPhone 6+ (414 x 736)
  • пустыня @2x ~ ipad: iPad (1024 x 768)

Ответ 8

В этом случае нет встроенной поддержки Assets, поэтому я думаю, что было бы лучше сделать это вручную, поскольку работа с недокументированными именами файлов может в будущем легко ломаться.

Ответ 9

Просто измерьте размеры устройства и вызовите нужное изображение. т.е. делать это программно

Итак, в вашем appdelegate есть глобальные

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

который вы можете вызывать повторно. Затем проверьте их и вызовите соответствующее изображение

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

Ответ 10

В моем случае, я был заинтересован в том, чтобы сделать мой подкласс класса базового представления тем же фоновым изображением, что и мой образ запуска.

ПРИМЕЧАНИЕ. Этот подход не будет работать, если это не является вашим конкретным требованием.

Кроме того, даже когда я попытался создать фоновое изображение, которое было правильным размером для iPhone 6 (750x1334), загрузка этого изображения в виде изображения шаблона в цвет фона для представления закончилась тем, что изображение уменьшилось нежелательно.

Этот ответ дал мне код, который мне нужен, чтобы найти хорошее решение для меня.

Здесь код, который я получил, чтобы изображение моего запуска совпало с фоновым изображением 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;
}

Ответ 11

Попробуйте этот класс, чтобы программно изменить название изображения.

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)[email protected]"
        case 414:
            return "\(imageName)[email protected]"
        default:
            return imageName
        }
    }
}

используйте этот метод следующим образом.

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

Ответ 12

FIRST, вам нужно настроить свой 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

Пожалуйста, дайте отзыв, если у вас возникнут проблемы.