Kích hoạt bố cục tự động trong iOS 6 trong khi vẫn tương thích ngược với iOS 5


153

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ì?


+1. Nơi bạn có thể tìm ra điều này? Có manh mối nào không?
Janak Nirmal

@Jennis Chưa. iOS 6 sẽ chính thức được phát hành vào ngày mai (19/9/2012). Hy vọng rằng bao gồm một số tài liệu bổ sung về chủ đề này.
sglantz

Tôi chưa tìm thấy gì cả. Tìm hiểu tâm trí muốn biết!
Ben Kreeger

Tôi không nghĩ rằng điều đó là có thể. Giống như bảng phân cảnh không thể có trên iOS4.
Leo Natan

Ngoài việc cung cấp hai tệp nib, tôi không thấy làm thế nào có thể. Nhưng tôi đồng ý với bạn.
Leo Natan

Câu trả lời:


120

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:

tài sản tự động thanh toán trong trình kiểm tra tệp

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ụ:

nhập mô tả hình ảnh ở đây

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ụ:

nhập mô tả hình ảnh ở đây

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.


29
Bố cục tự động yêu cầu iOS 6 trở lên. Nó không hoạt động với iOS 5! Vui lòng xác minh khiếu nại của bạn trước khi đăng. iOS 5 đơn giản là không có các API cần thiết (chẳng hạn như lớp NSLayoutConstraint). Nếu bạn không tin tôi, hãy kiểm tra những gì người dùng khác kinh nghiệm khi họ cố gắng sử dụng Autolayout với iOS 5: stackoverflow.com/questions/11252057/... stackoverflow.com/questions/11198981/...
Imre Kelényi

1
Có tôi nghĩ bạn đúng Tôi nghĩ rằng tôi đã nghe thấy nó trong một số video wwdc, nhưng bây giờ tôi đã thử nghiệm nó trên thiết bị iOS 5.0 và nó đã bị hỏng. Tôi sẽ xem qua các video này và kiểm tra xem tôi đã nghe thấy ở đâu. Tuy nhiên, bạn nói đúng là nó bị sập trên iOS 5.0
Asad Khan

@ ImreKelényi Bạn sẽ gửi cái này đến cửa hàng ứng dụng như thế nào? Tôi không quá quen thuộc với quy trình này, nhưng tôi nghĩ bạn đã gửi một tệp lưu trữ được nén của tệp .app. Có hai mục tiêu làm cho quá trình đó khó khăn hơn? Cảm ơn.
Pha lê

47

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


1
Bạn đúng rồi. Điều này hoạt động miễn là bạn tải 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" của mục tiêu trong Xcode. Tôi thêm một tài liệu tham khảo cho câu trả lời của bạn từ bài viết của tôi.
Imre Kelényi

SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TOlà 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/...
mờ

vâng, điểm tốt, không thực sự nghĩ về sự phục hồi khi tôi trả lời ban đầu
marchinram

Ahem, đừng sử dụng willFinishLaunchingWithOptions - Tôi đã nhận được "Ứng dụng chấm dứt do ngoại lệ chưa được xử lý 'NSInvalidUnarchiveOperationException', lý do: 'Không thể khởi tạo lớp có tên NSLayoutConstraint'" chạy trình giả lập trong iOS 5.1. Vấn đề không xảy ra với didFinishLaunchingWithOptions.
Elise van Looij


3

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'.



0

Tôi đã tìm thấy cài đặt kích thước chế độ xem chính của Xibs thành Freeform, và sau đó sử dụng Tự động hóa sẽ xử lý. Không có lỗi trong mã cho một vấn đề xem.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.