Как разработать или перенести приложения под разрешение экрана iPhone 5?

Новый дисплей iPhone 5 имеет новое соотношение сторон и новое разрешение (640 x 1136 пикселей).

Что требуется для разработки новых или перехода уже существующих приложений на новый размер экрана?

Что следует иметь в виду, чтобы сделать приложения "универсальными" как для старых дисплеев, так и для нового широкоэкранного соотношения сторон?

30 ответов

Решение
  1. Загрузите и установите последнюю версию Xcode.
  2. Установите файл экрана запуска для вашего приложения (на общей вкладке ваших целевых настроек). Вот как вы можете использовать полный размер любого экрана, включая размеры разделенного экрана iPad в iOS 9.
  3. Протестируйте свое приложение и, надеюсь, больше ничего не сделайте, поскольку все должно работать волшебным образом, если вы правильно установили маски автоматического изменения размера или использовали автоматическое расположение.
  4. Если вы этого не сделали, настройте макеты просмотра, предпочтительно с помощью Auto Layout.
  5. Если есть что-то, что вам нужно сделать для больших экранов, то похоже, что вы должны проверить высоту [[UIScreen mainScreen] bounds] поскольку, кажется, нет никакого специального API для этого. Начиная с iOS 8 есть также классы размеров, которые абстрагируют размеры экрана в обычный или компактный по вертикали и горизонтали и являются рекомендуемым способом адаптации вашего пользовательского интерфейса.

Если у вас есть приложение, созданное для iPhone 4S или более ранней версии, оно будет работать на почтовых ящиках на iPhone 5.

Чтобы адаптировать ваше приложение к новому более высокому экрану, первое, что вы должны сделать, это изменить образ запуска на: Default-568h@2x.png. Его размер должен быть 1136x640 (HxW). Да, наличие изображения по умолчанию в новом размере экрана - это ключ к тому, чтобы ваше приложение занимало весь экран нового iPhone 5.

(Обратите внимание, что соглашение об именах работает только для изображения по умолчанию. При присвоении имени другому изображению "Image-568h@2x.png" оно не будет загружаться вместо "Image@2x.png". Если вам нужно загрузить разные изображения для разных размеров экрана вам придется делать это программно.)

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

  • Убедитесь, что ваши Xibs/Views используют авто-макет для изменения размера.
  • Используйте пружины и распорки, чтобы изменить размеры просмотров.
  • Если этого недостаточно для вашего приложения, спроектируйте xib / storyboard для одного определенного размера экрана и программно измените положение для другого.

В крайнем случае (когда ничего из вышеперечисленного недостаточно) спроектируйте две Xibs и загрузите соответствующую в контроллере вида.

Чтобы определить размер экрана:

if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
{
    CGSize result = [[UIScreen mainScreen] bounds].size;
    if(result.height == 480)
    {
        // iPhone Classic
    }
    if(result.height == 568)
    {
        // iPhone 5
    }
}

Единственное, что действительно необходимо сделать, это добавить образ запуска "Default-568h@2x.png" к ресурсам приложения, и в общем случае (если вам повезет) приложение будет работать правильно.

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

[window setFrame:[[UIScreen mainScreen] bounds]]

Существуют и другие проблемы, не связанные с размером экрана при переходе на iOS 6. Дополнительные сведения см. В примечаниях к выпуску iOS 6.0.

Иногда (для приложений до раскадровки), если макет будет достаточно отличаться, стоит указать другой xib в зависимости от устройства (см. Этот вопрос - вам нужно изменить код для работы с iPhone 5) в viewController init, так как никакие изменения с масками авторазмера не будут работать, если вам нужна другая графика.

-(id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil

    NSString *myNibName;
    if ([MyDeviceInfoUtility isiPhone5]) myNibName = @"MyNibIP5";
    else myNibName = @"MyNib";

    if ((self = [super initWithNibName:myNibName bundle:nibBundleOrNil])) {


...

Это полезно для приложений, ориентированных на более старые версии iOS.

Здесь вы можете найти хороший учебник (для MonoTouch, но вы можете использовать информацию и для не-MonoTouch-проектов):
http://redth.info/get-your-monotouch-apps-ready-for-iphone-5-ios-6-today/

  1. Создайте новое изображение для вашего заставки / экрана по умолчанию (640 x 1136 пикселей) с именем "Default-568h@2x.png"

  2. В iOS Simulator перейдите в меню "Оборудование -> Устройство" и выберите "iPhone (Retina 4-inch)"

  3. Создание других изображений, например фоновых изображений

  4. Определите iPhone 5, чтобы загрузить новые изображения:

public static bool IsTall
{
    get {
        return UIDevice.currentDevice.userInterfaceIdiom
                    == UIUserInterfaceIdiomPhone
                && UIScreen.mainScreen.bounds.size.height
                    * UIScreen.mainScreen.scale >= 1136;
    }
}

private static string tallMagic = "-568h@2x";
public static UIImage FromBundle16x9(string path)
{
    //adopt the -568h@2x naming convention
    if(IsTall())
    {
        var imagePath = Path.GetDirectoryName(path.ToString());
        var imageFile = Path.GetFileNameWithoutExtension(path.ToString());
        var imageExt = Path.GetExtension(path.ToString());
        imageFile = imageFile + tallMagic + imageExt;
        return UIImage.FromFile(Path.Combine(imagePath,imageFile));
    }
    else
    {
        return UIImage.FromBundle(path.ToString());
    }
}

Легко переносить iPhone5 и iPhone4 через XIB.........

UIViewController *viewController3;
if ([[UIScreen mainScreen] bounds].size.height == 568)
{
    UIViewController *viewController3 = [[[mainscreenview alloc] initWithNibName:@"iphone5screen" bundle:nil] autorelease];               
}    
else
{
     UIViewController *viewController3 = [[[mainscreenview alloc] initWithNibName:@"iphone4screen" bundle:nil] autorelease];
}

Я решаю эту проблему здесь. Просто добавьте ~568h@2x суффикс к изображениям и ~ 568h к XIB. Не нужно больше проверок во время выполнения или изменения кода.

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

Затем я заметил, что в моем информационном списке есть позиция для "Launch image", установленная в "Default.png", которую я таким образом удалил, и магический почтовый ящик больше не появлялся. Надеюсь, это спасет кого-то еще от такого же безумия, которое я пережил.

Чтобы определить, может ли ваше приложение поддерживать iPhone 5 Retina, используйте это: (Это может быть более надежным, чтобы вернуть тип дисплея, 4S Retina и т. Д., Но, как написано ниже, оно просто возвращает, если iPhone поддерживает iOS5 Retina как Да или нет)

В общий файл ".h" добавьте:

BOOL IS_IPHONE5_RETINA(void);

В общий файл ".m" добавьте:

BOOL IS_IPHONE5_RETINA(void) {
    BOOL isiPhone5Retina = NO;
    if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
        if ([UIScreen mainScreen].scale == 2.0f) {
            CGSize result = [[UIScreen mainScreen] bounds].size;
            CGFloat scale = [UIScreen mainScreen].scale;
            result = CGSizeMake(result.width * scale, result.height * scale);

            if(result.height == 960){
                //NSLog(@"iPhone 4, 4s Retina Resolution");
            }
            if(result.height == 1136){
                //NSLog(@"iPhone 5 Resolution");
                isiPhone5Retina = YES;
            }
        } else {
            //NSLog(@"iPhone Standard Resolution");
        }
    }
    return isiPhone5Retina;
}

Я думаю, это не сработает во всех случаях, но в моем конкретном проекте это позволило мне избежать дублирования NIB-файлов:

Где-то в common.h Вы можете сделать эти определения исходя из высоты экрана:

#define HEIGHT_IPHONE_5 568
#define IS_IPHONE   ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
#define IS_IPHONE_5 ([[UIScreen mainScreen] bounds ].size.height == HEIGHT_IPHONE_5)

В вашем базовом контроллере:

- (void)viewDidLoad
{
    [super viewDidLoad];
    if (IS_IPHONE_5) {
        CGRect r = self.view.frame;
        r.size.height = HEIGHT_IPHONE_5 - 20;
        self.view.frame = r;
    }
    // now the view is stretched properly and not pushed to the bottom
    // it is pushed to the top instead...

    // other code goes here...
}

В constants.h В файл вы можете добавить эти определения операторов:

 #define IS_IPAD UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad 
 #define IS_IPHONE UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone
 #define IS_WIDESCREEN (fabs((double)[[UIScreen mainScreen] bounds].size.height - (double)568) < DBL_EPSILON) 
 #define IS_IPHONE_5 (!IS_IPAD && IS_WIDESCREEN)

Прежде всего создайте две xibs и прикрепите все делегаты, основной класс к xib и тогда вы можете поставить в это состояние, указанное ниже в вашем appdelegate.m файл в

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 

    if ([[UIScreen mainScreen] bounds].size.height == 568)
        {

        self.ViewController = [[ViewController alloc] initWithNibName:@"ViewControlleriphone5" bundle:nil];
        }

        else
        {
             self.ViewController = [[ViewController alloc] initWithNibName:@"ViewControlleriphone4" bundle:nil];

        }

Вы можете использовать его в любом месте программы, в зависимости от ваших потребностей, даже в вашем ViewController классы. Самое главное, что вы создали два xib файлы отдельно для iphone 4(320*480) and iphone 5(320*568)

Проверка bounds с 568 потерпит неудачу в ландшафтном режиме. iPhone 5 запускается только в портретном режиме, но если вы хотите поддерживать ротацию, то iPhone 5 "чек" должен будет справиться и с этим сценарием.

Вот макрос, который обрабатывает состояние ориентации:

#define IS_IPHONE_5 (CGSizeEqualToSize([[UIScreen mainScreen] preferredMode].size, CGSizeMake(640, 1136)))

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

Попробуйте метод ниже в одноэлементном классе:

-(NSString *)typeOfDevice
    {
        if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
        {
            CGSize result = [[UIScreen mainScreen] bounds].size;
            if(result.height == 480)
            {
                return @"Iphone";
            }
            if(result.height == 568)
            {
                return @"Iphone 5";
            }
        }
        else{
            return @"Ipad";;
        }


        return @"Iphone";
    }

Вы можете использовать Auto Layout Придумайте и создайте дизайн с использованием разрешения экрана iPhone 5, и он будет работать как для 4-дюймовых, так и для 3,5-дюймовых устройств, но в этом случае у вас должно быть достаточно знаний менеджера компоновки.

Сначала покажите это изображение. На этом изображении вы видите предупреждение о поддержке Retina 4, поэтому щелкните по этому предупреждению и нажмите "Добавить", чтобы ваш заставка Retina 4 автоматически добавлялась в ваш проект.

Показать изображение здесь

и после того, как вы используете этот код:

if([[UIScreen mainScreen] bounds].size.height == 568)
    {
        // For iphone 5
    }
    else
    {
        // For iphone 4 or less
    }

Я никогда не сталкивался с такой проблемой ни с одним устройством, поскольку у меня была одна кодовая база для всех без каких-либо жестко закодированных значений. Что я делаю, так это чтобы в качестве ресурса использовалось изображение максимального размера вместо одного для каждого устройства. Например, я бы выбрал один для отображения сетчатки и отобразил бы его в качестве аспекта, чтобы он был таким же, как на каждом устройстве. Приходит к решению кадра кнопки, например, во время выполнения. Для этого я использую значение% в виде патента, например, если я хочу, чтобы ширина равнялась половине родительского вида, беру 50 % от родительского, и то же самое относится к высоте и центру.

С этим мне даже не нужны XIBS.

Вы можете использовать это определение для расчета, если вы используете iPhone 5 на основе размера экрана:

#define IS_IPHONE_5 ( fabs( ( double )[ [ UIScreen mainScreen ] bounds ].size.height - ( double )568 ) < DBL_EPSILON )

затем используйте простой if заявление:

    if (IS_IPHONE_5) {

    // What ever changes
    }

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

#define DEVICE_IS_IPHONE5 ([[UIScreen mainScreen] bounds].size.height == 568)

float height = DEVICE_IS_IPHONE5?568:480;
if (height == 568) {
    // 4"

} else {

    // 3"

}

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

button mySubmitButton 'Sumbit' (100,100,100,30 + 0,88,0,0) { ... }

Оттуда Canappi сгенерирует правильный код target-c, который определяет устройство, на котором работает приложение, и будет использовать:

(100,100,100,30) for iPhone4
(100,**188**,100,30) for iPhone 5

Canappi работает как Interface Builder и Story Board, за исключением того, что он находится в текстовой форме. Если у вас уже есть файлы XIB, вы можете преобразовать их, чтобы вам не пришлось заново создавать весь пользовательский интерфейс с нуля.

Это настоящий универсальный код, вы можете создать 3 разных раскадровки:

Установите универсальный режим вашего проекта и настройте основной сюжет iPhone с раскадровкой iPhone5 и ipad main с раскадровкой целевого iPad, теперь добавьте новую цель раскадровки для iphone и измените разрешение для iphone 4s или менее, теперь реализуйте свой AppDelegate.m

iPhone4 / 4s (то же самое для 3/3Gs) один для iPhone5 и сделать проект универсальным, с новой мишенью Storyboard для iPad, теперь на AppDelegate.m под didFinishLaunching добавить этот код:

    if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone){
        UIStoryboard *storyBoard;

        CGSize result = [[UIScreen mainScreen] bounds].size;
        CGFloat scale = [UIScreen mainScreen].scale;
        result = CGSizeMake(result.width *scale, result.height *scale);

//----------------HERE WE SETUP FOR IPHONE4/4s/iPod----------------------

        if(result.height == 960){
            storyBoard = [UIStoryboard storyboardWithName:@"iPhone4_Storyboard" bundle:nil];
            UIViewController *initViewController = [storyBoard instantiateInitialViewController];
            [self.window setRootViewController:initViewController];
        }

//----------------HERE WE SETUP FOR IPHONE3/3s/iPod----------------------

        if(result.height == 480){
            storyBoard = [UIStoryboard storyboardWithName:@"iPhone4_Storyboard" bundle:nil];
            UIViewController *initViewController = [storyBoard instantiateInitialViewController];
            [self.window setRootViewController:initViewController];
        }
    }

        return YES;
 }

Итак, вы создали универсальное приложение для iPhone 3/3Gs/4/4s/5 для всех поколений iPod и всех типов iPad

Не забудьте объединить все IMG с myImage.png а также myImage@2x.png

Вы можете добавить этот код:

if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone){
        if ([[UIScreen mainScreen] respondsToSelector: @selector(scale)]) {
            CGSize result = [[UIScreen mainScreen] bounds].size;
            CGFloat scale = [UIScreen mainScreen].scale;
            result = CGSizeMake(result.width * scale, result.height * scale);

            if(result.height == 960) {
                NSLog(@"iPhone 4 Resolution");
            }
            if(result.height == 1136) {
              NSLog(@"iPhone 5 Resolution");
            }
        }
        else{
            NSLog(@"Standard Resolution");
        }
    }

По моему мнению, лучший способ справиться с такими проблемами и избежать пары условий, необходимых для проверки высоты устройства, - это использовать относительный фрейм для представлений или любой элемент пользовательского интерфейса, который вы добавляете в свой вид, например: если вы добавляете какой-то элемент пользовательского интерфейса, который вам нужен, должен располагаться внизу или чуть выше панели вкладок, тогда вы должны взять начало координат y относительно высоты вашего представления или относительно панели вкладок (если есть), и у нас также есть свойство автоматического изменения размера. Я надеюсь, что это будет работать для вас

Если вам нужно преобразовать уже существующее приложение в универсальное, вам нужно выбрать соответствующий файл xib->show Utilities-> Show Size inspector.

В Инспекторе размеров вы можете увидеть Авторазмер, с помощью этого инструмента вы можете конвертировать в существующее приложение для iOS.

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

int h = [[UIScreen mainScreen] bounds].size.height;
int w = [[UIScreen mainScreen] bounds].size.width;
self.imageView.frame = CGRectMake(20, 80, (h-200), (w-100));

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

Существует небольшая проблема при тестировании как на iOS-устройстве, так и на iOS Simulator. Похоже, что симулятор (XCode 6.0.1) выдает переключаемые значения для ширины и высоты в [[UIScreen mainScreen] bounds].size в зависимости от ориентации устройства.

Так что это может быть проблемой при определении правильного физического размера экрана. Этот код также помогает выделить все 2014 года. Модели iPhone:

  • Айфон 4С
  • iPhone5 (и iPhone5s)
  • iPhone6 ​​(и iPhone6 ​​+)

Его также можно легко изменить, чтобы отличить, например, iPhone6 ​​от iPhone6 ​​+.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    CGSize iOSDeviceScreenSize = [[UIScreen mainScreen] bounds].size;

    if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone)
    {
        if (iOSDeviceScreenSize.width > 568 || // for iOS devices
            iOSDeviceScreenSize.height > 568) // for iOS simulator
        {   // iPhone 6 and iPhone 6+

            // Instantiate a new storyboard object using the storyboard file named Storyboard_iPhone6
            storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard_iPhone6" bundle:nil];

            NSLog(@"loaded iPhone6 Storyboard");
        }
        else if (iOSDeviceScreenSize.width == 568 || // for iOS devices
                 iOSDeviceScreenSize.height == 568) // for iOS simulator
        {   // iPhone 5 and iPod Touch 5th generation: 4 inch screen (diagonally measured)

            // Instantiate a new storyboard object using the storyboard file named Storyboard_iPhone5
            storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard_iPhone5" bundle:nil];

            NSLog(@"loaded iPhone5 Storyboard");
        }
        else
        {   // iPhone 3GS, 4, and 4S and iPod Touch 3rd and 4th generation: 3.5 inch screen (diagonally measured)

                // Instantiate a new storyboard object using the storyboard file named Storyboard_iPhone4
            storyboard = [UIStoryboard story    boardWithName:@"MainStoryboard_iPhone" bundle:nil];

                NSLog(@"loaded iPhone4 Storyboard");
        }
    }
    else if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad)
    {   // The iOS device = iPad

        storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard_iPadnew" bundle:nil];

        NSLog(@"loaded iPad Storyboard");
    }

    // rest my code
}

Используя xCode 5, выберите "Перенести в каталог активов" в Project>General.

Затем используйте "Показать в поиске", чтобы найти ваше изображение запуска, вы можете фиктивно отредактировать его так, чтобы оно было размером 640x1136, а затем перетащите его в каталог ресурсов, как показано на рисунке ниже.

Убедитесь, что в разделе iOS7 и iOS6 R4 есть изображение размером 640x1136. При следующем запуске приложения черные полосы исчезнут, и ваше приложение будет использовать 4-дюймовый экран.

введите описание изображения здесь

Использовать Auto Layout особенность для просмотров. Он автоматически настроится на все разрешения.

Создайте две xib для контроллера с именем контроллера с суффиксом ~iphone или ~ipad. Во время компиляции Xcode получит правильный xib в зависимости от устройства.

Используйте классы размеров, если вы хотите создать один xib для iPhone и iPad, если представление достаточно простое для переноса на iPhone и iPad.

Стоит заметить - в новом Xcode вы должны добавить этот файл изображения Default-568h@2x.png в ресурсы

Я бы посоветовал использовать Autoresizing Mask в ваших приложениях в соответствии с вашим интерфейсом интерфейса, это экономит много хлопот и лучше, чем создание разных интерфейсов для экранов iPhone 4 и 5.

Другие вопросы по тегам