Могу ли я использовать два xibs с одним диспетчером представлений - re: портирование на iPhone 5 - программирование
Подтвердить что ты не робот

Могу ли я использовать два xibs с одним диспетчером представлений - re: портирование на iPhone 5

Я только что отправил свое первое приложение в магазин приложений (yay было только что одобрено!). Теперь я хочу обновить его, чтобы работать с (лучше выглядеть) на более крупном экране iPhone 5. Я не намерен ничего менять, кроме как немного изменить макет для большего экрана.

ПРИМЕЧАНИЕ. Я не хочу, чтобы мой текущий xib растягивался.

Возможно ли создать два xib файла (то есть: скопировать мой текущий файл xib для главного экрана) и подключить их обоих к контроллеру представления и сделать так, чтобы при запуске приложения приложение обнаружило, есть ли iPhone 5 или более ранним экраном. Затем, в зависимости от того, какое устройство оно, покажите пользователю другой экран.

Я хочу, чтобы базовое приложение оставалось прежним. Все, что я хочу, это представить немного другой (более высокий) экран для пользователей iPhone 5 с несколькими кнопками/элементами, перемещаемыми для нового макета. Я иначе не буду добавлять или удалять что-либо из интерфейса.

Этот вопрос + вопрос показывает, как переключаться между iPhone или iPad. Итак, этот. Оба являются полезными, но я не знаю, как это изменить для того обстоятельства, когда пользователь использует iPhone 5 с большим экраном или iPhone 4S и ниже. Кроме того, они предполагают два контроллера вида. Мне нужен только один контроллер просмотра, так как абсолютно ничего не происходит в логике контроллера просмотра - меняется только размещение объектов на экране и все это делается в XIB.

Я должен подумать, что ответ должен состоять в том, что контроллер представления iteslf оценивает, какое устройство он работает, а затем представляет соответствующий xib? Да? Нет?

Если да, то как мне это сделать?

4b9b3361

Ответ 1

[Пересмотрен с полным ответом: 7 октября 2012 г.]

После значительных исследований я нашел ответ, частично на этой странице SO (которая показывает, как определить, какая версия iPhone работает на вашем приложении) и отчасти эта страница SO (показывающая, как иметь два xib, которые имеют один и тот же "Владелец файла" . Последняя часть головоломки (загрузка отдельного xib с помощью метода loadNibNamed:) Я нашел в главе 10 Отличный IOS-программирование в формате Big Nerd Ranch. Вот как:

  • Создайте второй xib (Файл, Новый..., Файл, выберите "Пользовательский интерфейс", выберите "Пусто" и сохраните его. Это создаст новый xib. В приведенном ниже примере мой классический xib (для 3.5 "iPhones) был назван TipMainViewController.xib. Я сохранил новый iPhone 5 xib с именем TipMainViewController-5.xib

  • Сделайте этот новый xib 'File Owner' тем же ViewController, что и ваш существующий xib. Для этого в новом файле xib выберите "Владельцы файлов". Затем в "Identity Inspector" выберите существующий View Controller в качестве пользовательского класса. В моем случае я выбрал "TipMainViewController".

  • Перетащите новый UIView на новый пустой холст xib. В новом инспекторе атрибутов UIView установите атрибут "Размер" на "Retina 4 Full Screen"

  • Выберите все содержимое существующего "Классического" 3.5 "xib", например: все ваши элементы управления, кнопки, селектора, метки и т.д. Скопируйте их и вставьте их в новый iPhone 5 xib. Измените размер/перемещение и т.д. их оптимизировать для iPhone 4 ".

  • Сделайте все подключения к/из File Owner, как и при создании исходного xib.

  • Наконец, в методе 'viewDidLoad' вашего 'single' ViewController вставьте следующую логику (используя, конечно, имена nib/xib):

    - (void)loadView
    {
        [super viewDidLoad];
        if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
        {
            CGSize result = [[UIScreen mainScreen] bounds].size;
            if(result.height == 480)
            {
              // iPhone Classic
              [[NSBundle mainBundle] loadNibNamed:@"TipMainViewController" owner:self options:nil];
            }
            if(result.height == 568)
            {
              // iPhone 5
              [[NSBundle mainBundle] loadNibNamed:@"TipMainViewController-5" owner:self options:nil];
            }
        }
    }
    

Ответ 2

Вот простой пример рабочего кода для контроллера вашего вида, который показывает, как загрузить myXib-5.xib на iPhone 5 и myXib.xib на iPhone/iPod, предшествующих iPhone 5:

- (void)loadView
{
    if([[UIScreen mainScreen] bounds].size.height == 568)
    {
        // iPhone 5
        self.view = [[NSBundle mainBundle] loadNibNamed:@"myXib-5" owner:self options:nil][0];
    }
    else
    {
        self.view = [[NSBundle mainBundle] loadNibNamed:@"myXib" owner:self options:nil][0];
    }
}

Предполагается, что вы ориентируетесь только на iPhone, а не на iPad, чтобы он был простым.

Свойство класса владельца файла XIB также должно быть установлено на контроллер представления, содержащий loadView.

Ответ 3

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

В случае, если кому-то еще нужно то же самое, вот что-то, чтобы вы начали.

Скажем, вы создали универсальное приложение, использующее стандарты именования nib/xib для ios для контроллеров представлений с xib с тем же именем:

Два встроенных значения по умолчанию для автоматической загрузки xib при отсутствии имени передаются initWithNibName:

  • ExampleViewController.xib [iphone default, когда nib назван пустым для Retina 3.5 Полный экран для классических макетов iphone 4/4s и т.д....]
  • ExampleViewController ~ ipad.xib [ipad/ipad mini default, когда nib named empty]

Теперь скажите, что вам нужны пользовательские xibs для iphone 5/5s в IB, используя опцию Retina 4 Full Screen, т.е. вы не хотите, чтобы 3.5 xib отображались для любых 568h устройств.

Здесь пользовательское соглашение об именах, использующее подход категории:

  • ExampleViewController-568h.xib [iphone non default/пользовательское соглашение об именах, когда имя ниба пустое для Retina 4 Full Screen (568h)]

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

https://gist.github.com/scottvrosenthal/4945884

ExampleViewController.m

#import "UIViewController+AppCategories.h"

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    nibNameOrNil = [UIViewController nibNamedForDevice:@"ExampleViewController"];

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

       // Do any additional customization 

    }

    return self;
}

UIViewController + AppCategories.h

#import <UIKit/UIKit.h>

@interface UIViewController (AppCategories)

   + (NSString*)nibNamedForDevice:(NSString*)name;

@end

UIViewController + AppCategories.m

// ExampleViewController.xib [iphone default when nib named empty for Retina 3.5 Full Screen]
// ExampleViewController-568h.xib [iphone custom naming convention when nib named empty for Retina 4 Full Screen (568h)]
// ExampleViewController~ipad.xib [ipad/ipad mini default when nib named empty]

#import "UIViewController+AppCategories.h"

@implementation UIViewController (AppCategories)

+ (NSString*)nibNamedForDevice:(NSString*)name
{

    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
    {
        if ([UIScreen mainScreen].bounds.size.height == 568)
        {
            //Check if there a path extension or not
            if (name.pathExtension.length) {
                name = [name stringByReplacingOccurrencesOfString: [NSString stringWithFormat:@".%@", name.pathExtension] withString: [NSString stringWithFormat:@"-568h.%@", name.pathExtension ]
                ];

            } else {
                name = [name stringByAppendingString:@"-568h"];
            }

            // if 568h nib is found
            NSString *nibExists = [[NSBundle mainBundle] pathForResource:name ofType:@"nib"];
            if (nibExists) {
                return name;
           }

        }
    }

    // just default to ios universal app naming convention for xibs
    return Nil;
}

@end