Який найкращий спосіб скористатися новими можливостями автоматичного компонування iOS 6, при цьому забезпечити сумісність зі старими пристроями на попередніх версіях iOS?
Який найкращий спосіб скористатися новими можливостями автоматичного компонування iOS 6, при цьому забезпечити сумісність зі старими пристроями на попередніх версіях iOS?
Відповіді:
Авторозкладку можна включити або вимкнути на кожному файлі .storyboard або .xib. Просто виберіть конкретний файл і змініть властивість "Використовувати автоматичний виклад" за допомогою інспектора файлів у Xcode:
Використання файлів інтерфейсу з підтримкою авторозподілу з цільовою метою розгортання, встановленою на версії iOS до 6.0, призводить до помилок компіляції, наприклад:
Помилка в MainStoryboard.storyboard: 3: Автоматичний макет на версії iOS до 6.0
Один з ваших варіантів використання автоматичного розкладу в проекті та збереження сумісності з iOS4-5 - це створення двох цілей : одна для цілі розгортання iOS 6.0 та друга для більш ранньої версії iOS, наприклад:
Ви також можете створити дві версії для кожного файлу розкадрів та файлів XIB, а також використовувати автовідклад, увімкнутий для цілі 6.0, а інший із попередньою ціллю, наприклад:
Потім ви додаєте MainStoryBoardAutoSize до фаз збірки iOS6, а інший файл до iOS4-цілі. Ви можете дізнатися більше про використання кількох цілей тут .
EDIT: Як зазначається у відповіді marchinram , якщо ви завантажуєте файли розкадрівки з коду і не використовуєте параметр "Main Storyboard" у Xcode для встановлення початкової таблиці, ви можете використовувати одну ціль.
Для мене вартість додаткової складності підтримання декількох цілей та файлів інтерфейсу, здається, переважає переваги використання автоматичного розкладу. За винятком кількох спеціальних випадків, ви, ймовірно, набагато краще використовувати звичайний старий автоматичний розмір (або layoutSubViews з коду) виключно, якщо потрібна сумісність iOS4-5.
Вам справді потрібні дві цілі? У мене це працює так: у мене є 2 розкадровки, як сказав Імре Келеній, одне з увімкненими автоматичними макетами, а інше без цього, тоді в делегаті програми я просто перевіряю, яку версію вони використовують, і вибираю потрібну дошку:
#import "AppDelegate.h"
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:(v) options:NSNumericSearch] != NSOrderedAscending)
@interface AppDelegate ()
@property (strong, nonatomic) UIViewController *initialViewController;
@end
@implementation AppDelegate
@synthesize window = _window;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UIStoryboard *mainStoryboard = nil;
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"6.0")) {
mainStoryboard = [UIStoryboard storyboardWithName:@"iPhone_iOS6" bundle:nil];
} else {
mainStoryboard = [UIStoryboard storyboardWithName:@"iPhone_iOS5" bundle:nil];
}
self.initialViewController = [mainStoryboard instantiateInitialViewController];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.rootViewController = self.initialViewController;
[self.window makeKeyAndVisible];
return YES;
}
@end
Досягнення 2-х цілей також працює, але мені здається непосильним
SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO
є надмірним. Просто перевіряйте клас iOS 6-єдиний проти нуля. Дивіться developer.apple.com/library/mac/#documentation/developertools/…
Якщо розбіжності у компонуванні не великі, використовувати елементи Springs і Struts набагато простіше для розташування елементів.
Натхненний однією цільовою ідеєю @ marchinram, це рішення, яке я нарешті придумав. Два рекламні дошки, один для підкосів та пружини та один для автоматичного розкладу. У цільовому підсумку я встановив розкладинку автомашини за замовчуванням. Потім у програмі appDelegate я перевіряю, чи потрібно мені завантажувати розгорнуту до 6.0 аркушів розкосів та пружин:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
Class cls = NSClassFromString (@"NSLayoutConstraint");
if (cls == nil) {
NSString *mainStoryboardName = nil;
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
mainStoryboardName = @"MainStoryboard_iPad_StrutsAndSprings";
} else {
mainStoryboardName = @"MainStoryboard_iPhone_StrutsAndSprings";
}
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:mainStoryboardName bundle:nil];
UIViewController *initialViewController = [mainStoryboard instantiateInitialViewController];
self.window.rootViewController = initialViewController;
[self.window makeKeyAndVisible];
}
Крім того, я встановив ціль розгортання розширювальної стрічки-і-пружини на iOS 5.1, а розгортку автомашини - на SDK Project (iOS 6.0).
Я дуже хотів зробити перемикач перед завантаженням за замовчуванням у раскадровці, у willFinishLaunchingWithOptions: але це призводить до "NSInvalidUnarchiveOperationException", причина: "Не вдалося інстанціювати клас з іменем NSLayoutConstraint" незалежно від того, що я намагався.
Спробуйте використовувати RRAutoLayout: https://github.com/RolandasRazma/RRAutoLayout Це резервний порт для iOS6 AutoLayout на iOS5.