Cách tốt nhất để tận dụng các tính năng bố trí tự động mới của iOS 6 trong khi vẫn cung cấp khả năng tương thích với các thiết bị cũ hơn trên các phiên bản iOS cũ hơn là gì?
Cách tốt nhất để tận dụng các tính năng bố trí tự động mới của iOS 6 trong khi vẫn cung cấp khả năng tương thích với các thiết bị cũ hơn trên các phiên bản iOS cũ hơn là gì?
Câu trả lời:
Tự động thanh toán có thể được bật hoặc tắt trên mỗi tệp .storyboard hoặc .xib. Chỉ cần chọn tệp cụ thể và sửa đổi thuộc tính "Sử dụng tự động xóa" bằng trình kiểm tra tệp trong Xcode:
Sử dụng các tệp giao diện tự động bật tự động với mục tiêu triển khai được đặt thành phiên bản iOS trước 6.0 dẫn đến lỗi biên dịch, ví dụ:
Lỗi trong MainStoryboard.storyboard: 3: Bố cục tự động trên các phiên bản iOS trước 6.0
Một trong những lựa chọn của bạn để sử dụng tự động thanh toán trong dự án và vẫn duy trì khả năng tương thích với iOS4-5 là tạo hai mục tiêu : một cho mục tiêu triển khai iOS 6.0 và một cho phiên bản iOS cũ hơn, ví dụ:
Bạn cũng có thể tạo hai phiên bản cho mỗi tệp Storyboard và XIB của mình và sử dụng tính năng tự động thanh toán được bật với mục tiêu 6.0 và phiên bản còn lại với mục tiêu kế thừa, ví dụ:
Sau đó, bạn thêm MainStoryBoardAutoSize vào các giai đoạn Xây dựng của mục tiêu iOS6 và tệp khác vào mục tiêu iOS4. Bạn có thể tìm hiểu thêm về việc sử dụng nhiều mục tiêu ở đây .
EDIT: Như câu trả lời của marchinram chỉ ra, nếu bạn tải các tệp bảng phân cảnh từ mã và không sử dụng cài đặt "Bảng phân cảnh chính" trong Xcode để đặt bảng phân cảnh ban đầu, bạn có thể sử dụng một mục tiêu duy nhất.
Đối với tôi, chi phí cho sự phức tạp thêm vào của việc duy trì nhiều mục tiêu và tệp giao diện dường như lớn hơn lợi ích của việc sử dụng tự động thanh toán. Ngoại trừ một vài trường hợp đặc biệt, có lẽ bạn nên sử dụng kích thước tự động cũ đơn giản (hoặc layoutSubViews từ mã) nếu cần khả năng tương thích iOS4-5.
Bạn có thực sự cần hai mục tiêu? Tôi đã làm cho nó hoạt động như thế này, tôi có 2 bảng phân cảnh như Imre Kelényi đã nói, một cái có bố trí tự động được bật và cái kia không có, sau đó trong đại biểu ứng dụng tôi chỉ cần kiểm tra phiên bản nào họ đang sử dụng và chọn bảng phân cảnh phù hợp:
#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
Có 2 mục tiêu hoạt động tốt nhưng có vẻ như quá mức với tôi
SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO
là quá mức cần thiết. Chỉ cần kiểm tra một lớp chỉ có iOS 6 so với con số không. Xem developer.apple.com/library/mac/#documentation/developertools/...
Nếu sự khác biệt về bố cục không lớn, việc sử dụng Springs và Struts để định vị các phần tử sẽ dễ dàng hơn rất nhiều .
Lấy cảm hứng từ một ý tưởng mục tiêu của @ marchinram, đây là giải pháp cuối cùng tôi đã đưa ra. Hai bảng phân cảnh, một cho thanh chống và lò xo và một cho tự động thanh toán. Trong tóm tắt mục tiêu, tôi đặt bảng phân cảnh tự động thanh toán làm mặc định. Sau đó, trong appDelegate, tôi kiểm tra xem tôi có cần tải bảng phân cảnh trước struts-and-Springs không:
- (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];
}
Ngoài ra, tôi đặt mục tiêu triển khai của bảng phân cảnh struts-and-Springs thành iOS 5.1 và của bảng phân cảnh tự động thanh toán thành Project SDK (iOS 6.0).
Tôi thực sự muốn thực hiện chuyển đổi trước khi mặc định trong bảng phân cảnh được tải, trong willFinishLaunchingWithOptions: nhưng điều đó dẫn đến một 'NSInvalidUnarchiveOperationException', lý do: 'Không thể khởi tạo lớp có tên NSLayoutConstraint'.
Hãy thử sử dụng RRAutoLayout: https://github.com/RolandasRazma/RRAutoLayout Đó là backport AutoLayout iOS6 cho iOS5.