การเปิดใช้งานเลย์เอาต์อัตโนมัติใน iOS 6 ในขณะที่เหลือถอยหลังเข้ากันได้กับ iOS 5


153

วิธีที่ดีที่สุดในการใช้ประโยชน์จากคุณลักษณะเลย์เอาต์อัตโนมัติใหม่ของ iOS 6 ในขณะที่ยังให้ความสามารถในการทำงานร่วมกับอุปกรณ์รุ่นเก่าบน iOS เวอร์ชันก่อนหน้านี้คืออะไร


+1 คุณจะหาสิ่งนี้ได้จากที่ไหน? เบาะแสใด ๆ
Janak Nirmal

@Jennis ยังไม่ iOS 6 จะเปิดตัวเป็นทางการในวันพรุ่งนี้ (9/19/2012) หวังว่าจะมีเอกสารพิเศษบางอย่างเกี่ยวกับเรื่องนี้
sglantz

ฉันยังไม่พบอะไรเลย จิตใจที่น่าสงสัยอยากรู้!
Ben Kreeger

ฉันไม่คิดว่าจะเป็นไปได้ เหมือนกระดานเรื่องราวบน iOS4 เป็นไปไม่ได้
Leo Natan

นอกเหนือจากการให้ไฟล์ปากกาสองไฟล์ฉันไม่เห็นว่ามันจะเป็นไปได้อย่างไร แต่ฉันเห็นด้วยกับคุณ
Leo Natan

คำตอบ:


120

Autolayout สามารถเปิดหรือปิดการใช้งานในแต่ละไฟล์. stboard หรือ. xib เพียงเลือกไฟล์ที่ต้องการและแก้ไขคุณสมบัติ "Use Autolayout" โดยใช้ตัวตรวจสอบไฟล์ใน Xcode:

คุณสมบัติ autolayout ใน File inspector

การใช้ไฟล์อินเทอร์เฟซที่เปิดใช้งานอัตโนมัติพร้อมเป้าหมายการปรับใช้ที่ตั้งค่าเป็นเวอร์ชั่น iOS ก่อนหน้า 6.0 ทำให้เกิดข้อผิดพลาดในการคอมไพล์เช่น:

ข้อผิดพลาดใน MainStoryboard.storyboard: 3: เลย์เอาต์อัตโนมัติใน iOS เวอร์ชันก่อนหน้า 6.0

หนึ่งในตัวเลือกของคุณเพื่อใช้การชำระอัตโนมัติในโครงการและยังคงความเข้ากันได้กับ iOS4-5 คือการสร้างสองเป้าหมาย : หนึ่งเป้าหมายสำหรับการปรับใช้เป้าหมาย iOS 6.0 และอีกหนึ่งสำหรับเวอร์ชัน iOS รุ่นก่อนหน้าเช่น

ป้อนคำอธิบายรูปภาพที่นี่

คุณสามารถสร้างสองเวอร์ชั่นสำหรับไฟล์สตอรี่บอร์ดและไฟล์ XIB ของคุณแต่ละไฟล์ได้เช่นกันและใช้การเปิดใช้อัตโนมัติอัตโนมัติที่เปิดใช้งานด้วยเป้าหมาย 6.0 และอีกรุ่นหนึ่งที่มีเป้าหมายดั้งเดิมเช่น:

ป้อนคำอธิบายรูปภาพที่นี่

จากนั้นคุณเพิ่ม MainStoryBoardAutoSize ให้กับขั้นตอนการสร้างเป้าหมาย iOS6 และไฟล์อื่น ๆ ไปยังเป้าหมาย iOS4 คุณสามารถเรียนรู้เพิ่มเติมเกี่ยวกับการใช้เป้าหมายหลายที่นี่

แก้ไข: ตามคำตอบของ marchinramหากคุณโหลดไฟล์สตอรีบอร์ดของคุณจากรหัสและอย่าใช้การตั้งค่า "กระดานเรื่องราวหลัก" ใน Xcode เพื่อตั้งกระดานเรื่องราวเริ่มต้นคุณสามารถใช้เป้าหมายเดียว

สำหรับฉันค่าใช้จ่ายของความซับซ้อนที่เพิ่มขึ้นในการรักษาเป้าหมายและไฟล์อินเทอร์เฟซหลายรายการดูเหมือนว่าจะเกินดุลประโยชน์ของการใช้ autolayout ยกเว้นบางกรณีพิเศษคุณน่าจะใช้การปรับขนาดอัตโนมัติแบบธรรมดา (หรือ layoutSubViews จากรหัส) ได้ดีกว่าถ้าจำเป็นต้องใช้ความเข้ากันได้กับ iOS4-5


29
เลย์เอาต์อัตโนมัติต้องใช้ iOS 6 หรือใหม่กว่า มันไม่ทำงานกับ iOS 5! โปรดตรวจสอบการอ้างสิทธิ์ของคุณก่อนโพสต์ iOS 5 นั้นไม่มี API ที่จำเป็น (เช่นคลาส NSLayoutConstraint) ถ้าคุณไม่เชื่อฉันตรวจสอบสิ่งที่ผู้ใช้มีประสบการณ์อื่น ๆ เมื่อพวกเขาพยายามที่จะใช้ autolayout กับ iOS 5: stackoverflow.com/questions/11252057/... stackoverflow.com/questions/11198981/...
แฟลเลิKelényi

1
ใช่ฉันคิดว่าคุณพูดถูกฉันคิดว่าฉันได้ยินมันในวิดีโอ wwdc บางตัว แต่ตอนนี้ฉันทดสอบบนอุปกรณ์ iOS 5.0 และมันล้มเหลว ฉันจะผ่านวิดีโอเหล่านี้และตรวจสอบว่าฉันได้ยินมันที่ไหน แต่อย่างไรก็ตามคุณพูดถูกมันผิดพลาดใน iOS 5.0
Asad Khan

@ ImreKelényiคุณจะส่งสิ่งนี้ต่อ app store อย่างไร? ฉันไม่คุ้นเคยกับขั้นตอนนี้มากนัก แต่ฉันคิดว่าคุณจะส่งไฟล์เก็บถาวรของไฟล์. app ของคุณหนึ่งไฟล์ การมีสองเป้าหมายทำให้กระบวนการนั้นยากขึ้นหรือไม่ ขอบคุณ
คริสตัล

47

คุณต้องการสองเป้าหมายจริงๆหรือ ฉันได้มันทำงานแบบนี้ฉันมี 2 กระดานเรื่องราวเหมือน Imre Kelényiกล่าวว่าหนึ่งมีการเปิดใช้งานรูปแบบอัตโนมัติและอื่น ๆ โดยไม่ต้องจากนั้นในตัวแทนแอปฉันแค่ตรวจสอบรุ่นที่พวกเขากำลังใช้และเลือกกระดานเรื่องราวที่เหมาะสม:

#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 เป้าหมายทำงานได้ดีเช่นกัน แต่ดูเหมือนว่าจะเกินความคิดของฉัน


1
คุณพูดถูก ใช้งานได้ตราบใดที่คุณโหลดสตอรีบอร์ดจากโค้ดและห้ามใช้การตั้งค่า "Main Storyboard" ของเป้าหมายใน Xcode ฉันเพิ่มการอ้างอิงถึงคำตอบของคุณจากโพสต์ของฉัน
Imre Kelényi

SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TOเป็น overkill เพียงทดสอบคลาส iOS 6 เท่านั้นกับไม่มี ดูdeveloper.apple.com/library/mac/#documentation/developertools/…
แม

ใช่คะแนนที่ดีไม่ได้คิดเกี่ยวกับการฟื้นฟูเมื่อฉันตอบครั้งแรก
marchinram

อะแฮ่มไม่ได้ใช้ willFinishLaunchingWithOptions - ฉันได้รับ "แอพสิ้นสุดเนื่องจากข้อยกเว้นที่ไม่ได้ตรวจสอบ 'NSInvalidUnarchiveOperationException' เหตุผล: 'ไม่สามารถยกตัวอย่างคลาสที่ชื่อว่า ปัญหาไม่ได้เกิดขึ้นกับ didFinishLaunchingWithOptions
Elise van Looij


3

แรงบันดาลใจจากแนวคิดหนึ่งในเป้าหมายของ @ marchinram นี่คือทางออกที่ฉันได้มาในที่สุด สองกระดานเรื่องราวหนึ่งกระดานสำหรับเสาและสปริงและอีกกระดานหนึ่งสำหรับการเล่นอัตโนมัติ ในสรุปเป้าหมายฉันตั้งกระดานเรื่องราวอัตโนมัติเป็นค่าเริ่มต้น จากนั้นในแอปที่ได้รับมอบหมายฉันจะตรวจสอบว่าฉันต้องโหลดสตอรี่บอร์ดสตรัทและสตรอเบอร์รีก่อนหน้า 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 และกระดานเรื่องราวอัตโนมัติเพื่อเป็น Project SDK (iOS 6.0)

ฉันอยากจะเปลี่ยนก่อนที่จะโหลดค่าเริ่มต้นในสตอรีบอร์ดใน willFinishLaunchingWithOptions: แต่นั่นจะส่งผลใน 'NSInvalidUnarchiveOperationException' เหตุผล: 'ไม่สามารถยกตัวอย่างคลาสที่ชื่อว่า NSLayoutConstraint' ไม่ว่าฉันจะพยายามทำอะไรก็ตาม



0

ฉันพบว่าการตั้งค่าขนาดมุมมองหลักของ Xibs ให้เป็นอิสระแล้วใช้การปรับขนาดอัตโนมัติเป็นวิธีการรักษา ไม่มีการยุ่งเกี่ยวกับในรหัสสำหรับปัญหาการดู

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.