Разные перья для разных устройств

Итак, я пишу приложение и хочу, чтобы оно было универсальным. Когда я создавал проект, я создал универсальное приложение. Я написал весь код для iPhone и у меня около 10 классов. Теперь я хочу создать версию для iPad. Вместо того, чтобы иметь два набора классов с практически одинаковым кодом, я хотел бы загрузить другой Nib в зависимости от типа устройства.

Я попытался использовать BOOL в делегате приложения, и у меня возникли проблемы с этим. Я попробовал проверить устройство в классе mainViewController (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil. Я вернул другой наконечник в зависимости от типа устройства. Но я мог получить только версию для iphone или чистый наконечник. Заранее благодарю за любую помощь.


person Andrew    schedule 08.04.2011    source источник


Ответы (4)


В соответствии с документацией (Руководство по программированию ресурсов) вы можете использовать соглашение об именах, например: myNibName~ipad.xib и myNibName~iphone.xib, поэтому каждый файл будет открыт только на поддерживаемом устройстве. Вам даже не нужно устанавливать разные appDelegates :)

--- из документа --- В iOS 4.0 и более поздних версиях можно пометить отдельные файлы ресурсов как пригодные для использования только на устройствах определенного типа. Эта возможность упрощает код, который вам нужно написать для универсальных приложений. Вместо того, чтобы создавать отдельные пути кода для загрузки одной версии файла ресурсов для iPhone и другой версии файла для iPad, вы можете позволить процедурам загрузки пакета выбрать правильный файл. Все, что вам нужно сделать, это правильно назвать файлы ресурсов.

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

.

Строка представляет исходное имя файла ресурсов. Он также представляет имя, которое вы используете при доступе к файлу из своего кода. Точно так же строка является стандартным расширением имени файла, используемым для идентификации типа файла. Строка — это чувствительная к регистру строка, которая может принимать одно из следующих значений:

~ipad — ресурс должен загружаться только на устройствах iPad. ~iphone — ресурс должен загружаться только на устройства iPhone или iPod touch.

person WezUwiUsz    schedule 08.04.2011
comment
Строчная буква «p» в «~ipad» и «~iphone» показалась мне неправильной, но это действительно то, что описывает Apple. Ссылка на документацию: developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ - person Johan Kool; 20.03.2012
comment
Строчная буква «p» очень важна. ~iPad будет работать в эмуляторе, но не будет загружаться на реальном устройстве. Некоторые версии XCode создают ~ файлы iPad (с заглавной буквой «P»), что вводит в заблуждение и не работает. - person Wojciech Beling; 27.03.2012
comment
^^ Спасибо Йохану и Вой. Мне самому было любопытно об этом. - person Cyprus106; 30.04.2014

Теперь Apple предоставляет вам механизм по умолчанию для разделения кода между iPhone и iPad в рамках одного проекта.

В Xcode 4, когда вы создаете новое «приложение на основе окна» или «приложение на основе представления», вам предоставляется возможность выбрать «семейство устройств». Если вы выберете «Универсальный» для этой опции, Xcode создаст 3 делегата приложения.

Во-первых, основной делегат приложения:

YourAppNameAppDelegate : NSObject <UIApplicationDelegate> 

и два других делегата приложения (помещенные в отдельные группы), которые являются подклассами «YourAppNameAppDelegate»:

YourAppNameAppDelegate_iPhone : YourAppNameAppDelegate
YourAppNameAppDelegate_iPad : YourAppNameAppDelegate

Когда вы запускаете свое приложение с помощью симулятора (или устройства) iPhone или iPad, приложение будет автоматически использовать подкласс делегата приложения _iPhone или _iPad в зависимости от выбранного устройства.

Если вы переопределите метод application:didFinishLaunchingWithOptions: в каждом подклассе, вы увидите, что это работает:

// In YourAppNameAppDelegate_iPhone.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    NSLog(@"iPhone App Delegate");
    return [super application:application didFinishLaunchingWithOptions:launchOptions];
}

// In YourAppNameAppDelegate_iPad.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    NSLog(@"iPad App Delegate");
    return [super application:application didFinishLaunchingWithOptions:launchOptions];
}

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

Когда вы добавляете новые контроллеры представления в свой проект, вы должны продолжить эту парадигму, создав один общий суперкласс контроллера и подкласс, специфичный для iPhone/iPad. Обратите внимание, что общие суперклассы не должны иметь связанных с ними файлов пера, в то время как подклассы должны иметь каждый свой собственный отдельный кончик.

Таким образом, вы можете разбить свой код между тремя классами, сохраняя в суперклассе вещи, не зависящие от платформы, например, некоторые свойства, методы, IBOutlets и IBActions, и помещать специфичные для платформы реализации в любой из подклассов.

person Jo-el    schedule 08.04.2011
comment
какая-то причина, по которой вы не переключаетесь? это бесплатно.. developer.apple.com/xcode - person Jo-el; 12.04.2011
comment
xcode 4 выпущен публично или находится в бета-версии? Я видел, что это была бета-версия, посмотрел на все основные изменения и просто решил, что буду придерживаться того, с чем у меня ничего не получается. Я не очень часто захожу на dev.apple.com - person Andrew; 12.04.2011
comment
Это публично выпущено. Хотя я ошибся, это бесплатно только в том случае, если вы являетесь частью программы разработчика iOS. 4,99 доллара в противном случае. - person Jo-el; 12.04.2011
comment
Я участвую в платной программе для разработчиков iOS. Я думаю, я получу это - person Andrew; 12.04.2011

У меня была эта проблема, и я решил ее, настроив метод initWithNibName:bundle: UIViewController.

- (id) initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle*)nibBundleOrNil
{
  // See below for definition of "LWEUniversalAppHelpers fileNamed:"
  NSString *universalNibName = [LWEUniversalAppHelpers fileNamed:nibNameOrNil];
  if ((self = [super initWithNibName:universalNibName bundle:nibBundleOrNil]))
  {
    // Custom initialization
  }
  return self;
}

LWEUniversalAppHelpers — это вспомогательный класс, написанный моей компанией для определения, является ли устройство iPad или нет. Это общедоступно на GitHub, но основная концепция заключается в использовании политики Retina «@2x», но вместо этого мы используем «@HD».

person makdad    schedule 08.04.2011
comment
выглядит круто, но что происходит, когда у iPad 3 или 4 есть дисплей Retina, а вы застряли с @HD@2x. Это будет беспорядок. - person Moshe; 11.04.2011

Я понял, как:

в Interface Builder используйте File->Create ipad version

затем сохраните файл и добавьте его в проект. Затем при распределении инициализируйте каждый viewController, проверьте, есть ли UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad, а еще это iPhone или iPod Touch. У меня были проблемы с внесением изменений в него после первоначального сохранения, но он работает.

person Andrew    schedule 11.04.2011