วิธีที่ดีที่สุดในการใช้ประโยชน์จากคุณลักษณะเลย์เอาต์อัตโนมัติใหม่ของ iOS 6 ในขณะที่ยังให้ความสามารถในการทำงานร่วมกับอุปกรณ์รุ่นเก่าบน iOS เวอร์ชันก่อนหน้านี้คืออะไร
วิธีที่ดีที่สุดในการใช้ประโยชน์จากคุณลักษณะเลย์เอาต์อัตโนมัติใหม่ของ iOS 6 ในขณะที่ยังให้ความสามารถในการทำงานร่วมกับอุปกรณ์รุ่นเก่าบน iOS เวอร์ชันก่อนหน้านี้คืออะไร
คำตอบ:
Autolayout สามารถเปิดหรือปิดการใช้งานในแต่ละไฟล์. stboard หรือ. xib เพียงเลือกไฟล์ที่ต้องการและแก้ไขคุณสมบัติ "Use Autolayout" โดยใช้ตัวตรวจสอบไฟล์ใน Xcode:
การใช้ไฟล์อินเทอร์เฟซที่เปิดใช้งานอัตโนมัติพร้อมเป้าหมายการปรับใช้ที่ตั้งค่าเป็นเวอร์ชั่น 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
คุณต้องการสองเป้าหมายจริงๆหรือ ฉันได้มันทำงานแบบนี้ฉันมี 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 เป้าหมายทำงานได้ดีเช่นกัน แต่ดูเหมือนว่าจะเกินความคิดของฉัน
SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO
เป็น overkill เพียงทดสอบคลาส iOS 6 เท่านั้นกับไม่มี ดูdeveloper.apple.com/library/mac/#documentation/developertools/…
หากความแตกต่างของเลย์เอาต์ไม่ใหญ่มันง่ายกว่ามากที่จะใช้Springs และ Strutsเพื่อจัดวางองค์ประกอบ
แรงบันดาลใจจากแนวคิดหนึ่งในเป้าหมายของ @ 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' ไม่ว่าฉันจะพยายามทำอะไรก็ตาม
ลองใช้ RRAutoLayout: https://github.com/RolandasRazma/RRAutoLayout เป็น iOS6 AutoLayout backport เป็น iOS5
ฉันพบว่าการตั้งค่าขนาดมุมมองหลักของ Xibs ให้เป็นอิสระแล้วใช้การปรับขนาดอัตโนมัติเป็นวิธีการรักษา ไม่มีการยุ่งเกี่ยวกับในรหัสสำหรับปัญหาการดู