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



скажем, я хочу, чтобы связанное изображение занимало всю доступную ширину экрана в приложении для iPhone - например, баннер. Я бы создал my_banner.png шириной 320px,[email protected] шириной 640px и [email protected] на iPhone 6 plus шириной 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)

718   12  

12 ответов:

мне кажется, что многие из этих ответов хотят решить, как ограничить 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

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

  • каталог активов для конкретных устройств
  • укажите изображения для 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"];
}

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

автоматический макет должен помочь в этой ситуации..

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

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

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

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

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

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

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

убедитесь, что если вы используете auto layout, то check pin установлен в ноль для всех ребер и ограничений на маржу не проверяется.

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

enter image description here

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

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

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

  • desert@2x: iPhone 4s (320 x 420)
  • пустыня-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)

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

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

Так что в вашем appdelegate есть глобалы

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

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

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

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

Примечание: этот подход не будет работать, если это не ваше конкретное требование.

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

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

вот код, который я получил, чтобы мой образ запуска соответствовал моему UIViewController's фоновое изображение (или наоборот):

- (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;
}

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

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"))

первый из всех, вам нужно настроить imageView, чтобы покрыть весь экран,Autolayout поможет много для этой работы, взгляните на ссылку ниже и найдите, как закрепить ограничения (ведущее пространство, конечное пространство, верхнее пространство и нижнее пространство) С помощью раскадровки:

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

enter image description here

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

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

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

Comments

    Ничего не найдено.