ฉันเพิ่งสังเกตเห็นคุณสมบัติเดลต้า iOS 6/7 ที่พบภายใต้โครงร่างโครงสร้างของ UIView
สิ่งนี้มีไว้เพื่ออะไรและเหตุใดจึงหายไปจาก AutoLayout
ฉันเพิ่งสังเกตเห็นคุณสมบัติเดลต้า iOS 6/7 ที่พบภายใต้โครงร่างโครงสร้างของ UIView
สิ่งนี้มีไว้เพื่ออะไรและเหตุใดจึงหายไปจาก AutoLayout
คำตอบ:
อันนี้หมายถึง Delta ระหว่างตำแหน่งเลย์เอาต์จาก iOS6 ถึง iOS7
ใน iOS7 มุมมองบางอย่างสามารถซ่อนแถบสถานะหรือทำให้โปร่งใสและมีผลบังคับใช้มันจะซ้อนทับบนมุมมองของคุณ ดังนั้นหากคุณใส่องค์ประกอบ UI ไว้ที่ (0.0, 0.0) บน iOS6 องค์ประกอบนั้นจะปรากฏด้านล่างแถบสถานะ แต่บน iOS7 จะปรากฏอยู่บางส่วนอยู่ใต้แถบสถานะ ดังนั้นในกรณีนี้คุณต้องการเดลต้าที่ตรงกับความสูงของแถบสถานะ (20.0 คะแนน) เพื่อให้เค้าโครงดูเหมือนกันใน iOS6 และ iOS7
ฉันเชื่อว่าสิ่งนี้ไม่จำเป็นหากคุณใช้การจัดวางอัตโนมัติ แต่แน่นอนว่าคุณจะสูญเสียการรองรับ iPad1 ซึ่งพวกเราหลายคนไม่เต็มใจที่จะยอมรับในเวลานี้
หมายเหตุ: ฉันสังเกตเห็นคำถามนี้เมื่อไม่นานมานี้ แต่ตอนนี้ฉันเพิ่งโพสต์คำตอบเพราะ NDA ถูกยกขึ้น
อย่างที่คุณสังเกตเห็น iOS 7 นำเสนอรูปลักษณ์ใหม่ทั้งหมด รูปลักษณ์ขององค์ประกอบ UI เปลี่ยนไป แต่ก็มีขนาด (หรือเมตริกโดยทั่วไป) ด้วย สิ่งนี้สามารถทำให้การออกแบบอินเทอร์เฟซรองรับทั้ง iOS 7 และรุ่นก่อน ๆ ค่อนข้างลำบาก
สายอย่างเป็นทางการของ Apple คือการใช้ AutoLayout เพื่อแก้ปัญหานี้ สิ่งนี้จะช่วยลดความยุ่งยากในการจัดวางองค์ประกอบ UI ให้กับคุณ บางครั้งการรวมสิ่งนี้ไม่สามารถทำได้อย่างง่ายดายโดยเฉพาะอย่างยิ่งหากคุณยังต้องรองรับ iOS 5 ด้วยเหตุผลทางธุรกิจหรืออินเทอร์เฟซของคุณได้รับการจัดการในลักษณะที่ทำให้การใช้งาน AutoLayout เป็นเรื่องยาก ด้วยเหตุนี้ดูเหมือนว่า Apple จะจัดหาวิธีที่จะทำให้งานของคุณง่ายขึ้นเล็กน้อยหากคุณอยู่ในหมวดหมู่เฉพาะนี้และพวกเขาเรียกสิ่งนี้ว่า iOS 6/7 Deltas
ในขณะที่ป้ายกำกับในตัวสร้างอินเทอร์เฟซนั้นค่อนข้างไม่ชัดเจนว่า 'Delta' หมายถึงอะไรในบริบทนี้โค้ดที่อยู่ในไฟล์. xib ที่ตรงกับคุณสมบัตินี้จะชัดเจนกว่าเล็กน้อย:
<inset key="insetFor6xAndEarlier" minX="-50" minY="-100" maxX="-50" maxY="300"/>
ชื่อคีย์ระบุinsetFor6xAndEarlier
อย่างชัดเจนว่าสิ่งนี้ทำอะไร คุณสามารถใส่สิ่งที่ใส่เข้าไปทางเลือกสำหรับองค์ประกอบ UI ได้เมื่อรันบนรุ่นก่อนของ iOS 7 ตัวอย่างเช่นข้างต้นกำหนดการเปลี่ยนแปลงเดลต้าต่อไปนี้:
x: 50
y: 100
width: -100
height: 200
แม้ว่าค่าที่จัดเก็บใน. xib จะไม่ตรงกับค่าที่ยกมาโดยตรง แต่ก็มีความสัมพันธ์กัน
x: -minX
y: -minY
width: minX + maxX
height: minY + maxY
ภาพด้านล่างแสดงการเปลี่ยนแปลงนี้ทางสายตา เป็นตัวอย่างที่ค่อนข้างรุนแรง แต่เป็นการแสดงให้เห็นถึงความสามารถของมัน ในทางปฏิบัติฉันคาดหวังว่าจะมีการเปลี่ยนแปลงเดลต้าเพียงไม่กี่พิกเซลเท่านั้น
คุณอาจสังเกตเห็นว่าค่าเป็นค่าผกผันสำหรับมุมมอง iOS 6 เนื่องจากเดลต้าสัมพันธ์กับประเภทของมุมมองที่คุณกำลังทำงานด้วย หากคุณกำลังแก้ไข iOS 6 เดลต้าจะมีเพื่อเปลี่ยนองค์ประกอบให้ถูกต้องสำหรับ iOS 7 (ย้อนกลับของตัวอย่างด้านบน)
ในการดูรูปแบบต่างๆคุณสามารถเปลี่ยนวิธีที่ตัวสร้างอินเทอร์เฟซนำเสนอตามระบบปฏิบัติการที่จะใช้งานได้ สิ่งนี้มีอยู่ใน File Inspector-> Interface Builder Document (แท็บที่ 1 บนแถบด้านขวา) ดังนี้:
ไม่โดยตรง แต่คุณสามารถบรรลุผลเช่นเดียวกันได้อย่างง่ายดายโดยมีการตรวจสอบตามเงื่อนไขเกี่ยวกับเวอร์ชันของระบบปฏิบัติการภายในรหัสของคุณและตั้งค่าตำแหน่ง / ขนาดที่ถูกต้องตามนั้น ความสามารถของเดลต้ามีอยู่ในตัวสร้างอินเทอร์เฟซเนื่องจากไม่มีวิธีที่ตรงไปตรงมาในการวางตำแหน่งตามเงื่อนไขโดยไม่ต้องมีโค้ดในการทำและจุดของตัวสร้างอินเทอร์เฟซคือการได้รับโค้ดมากที่สุดเท่าที่จะเป็นไปได้สำหรับ UI
Apple ขอแนะนำให้คุณใช้ AutoLayout ซึ่งจะทำให้ชีวิตของคุณง่ายขึ้นในกรณีส่วนใหญ่ หากคุณไม่สามารถใช้งานได้ (ด้วยเหตุผลที่กล่าวไว้ข้างต้น) เดลต้าจะช่วยให้คุณมีความยืดหยุ่นในการวางตำแหน่งองค์ประกอบ UI ของคุณได้อย่างเหมาะสมโดยอิงตามเมตริกของระบบปฏิบัติการปัจจุบันโดยไม่จำเป็นต้องเปลี่ยนตำแหน่งด้วยตนเองในโค้ด ตัวอย่างที่ดีคือการปรับแถบสถานะ แต่ยังมีกรณีการใช้งานอื่น ๆ อีกมากมาย
โดยปกติแล้วหากคุณพัฒนาเฉพาะ iOS7 ขึ้นไปคุณไม่จำเป็นต้องรู้คุณสมบัตินี้ / จะไม่ค้นพบ เฉพาะในกรณีที่คุณจำเป็นต้องมีอุปกรณ์ iOS6 ที่ใช้งานแอปพลิเคชันของคุณเมื่อสร้างด้วย iOS7 SDK โดยไม่ต้องมีการจัดวางอัตโนมัติคุณจำเป็นต้องมีเดลต้า
ในขณะที่เขียน (21 สิงหาคม) ฉันไม่พบเอกสารใด ๆ เกี่ยวกับคุณลักษณะนี้หรือไม่มีการกล่าวถึงในเนื้อหาของ WWDC ฉันได้ลองเล่นและหลังจากการค้นคว้าข้อมูลเล็กน้อยนั่นคือสิ่งที่ฉันค้นพบ
ฉันรู้ว่าสิ่งนี้ได้รับคำตอบแล้วเพียงแค่เพิ่มตัวแปรเล็ก ๆ หวังว่ามันจะช่วยผู้ที่ไม่ได้ใช้เลย์เอาต์อัตโนมัติและยังต้องการรองรับ iOS 6.1 และเวอร์ชันก่อนหน้า
อ่านคู่มือการเปลี่ยนของ Apple - รองรับเวอร์ชันก่อนหน้านี้
เลือก 'ดูเป็น' เป็น 'iOS 7.0 ขึ้นไป'
UI พื้นฐานสำหรับ iOS 7 สำหรับ iOS 6 ให้ค่าเดลต้าที่เหมาะสม ใช้การแสดงตัวอย่างเพื่อดูว่าจะแสดงผลอย่างไรในอุปกรณ์ iOS 7 และ iOS 6
ขั้นตอนด่วน:
เลือกชายด์ทันทีของมุมมองรูททีละรายการและเพิ่ม 20px ให้กับค่า 'Y'
จากนั้นเลือกชายด์ทั้งหมดในทันทีโดยรวมและกำหนดเดลต้า Y เป็น -20px นอกจากนี้คุณยังสามารถทำได้เป็นชุดหรือทีละรายการ
AutoLayout ต้องการ iOS 6.0 เป็นอย่างน้อย หากคุณต้องการรองรับ iOS 5.0 คุณไม่สามารถใช้ AutoLayout ได้
และเดลต้าเหล่านั้นใช้เพื่อช่วยคุณปรับตำแหน่งมุมมองใน iOS เวอร์ชันต่างๆ (ส่วนใหญ่เป็น iOS 7 และ iOS เวอร์ชันต่ำกว่า 7)
ฉันใช้ค่าเหล่านั้นเพื่อช่วยฉันชอบภาพนี้
หากต้องการดูการทำงานของ iOS 6/7 Delta ฉันจะสาธิตด้วย SegmentedControl ที่ปรากฏอย่างถูกต้องบนอุปกรณ์ iOS 6 และ iOS 7
ขั้นแรกเลือก. Xib หรือ ViewController ของคุณใน Storyboard ยกเลิกการเลือกUse Autolayoutและเลือก " View as iOS 7 and later "
ในผ้าใบตัวสร้างอินเทอร์เฟซให้วาง SegmentedControl ของคุณเพื่อให้จุดเริ่มต้นyคือ 20 ใน iOS 6/7 Delta ให้เลือก -20 สำหรับ DeltaY
สิ่งนี้จะทำให้ SegmentedControl ของคุณวางไว้ใต้แถบสถานะในอุปกรณ์ iOS 6 และ iOS 7
คำพูดที่เป็นประโยชน์อีกอย่างจากคู่มือนักพัฒนาสำหรับแถบสถานะ iOS 7
สามารถตั้งค่า Deltas แยกกันสำหรับแต่ละมุมมองและทำงานได้ตามที่คุณคาดหวัง หากสตอรีบอร์ดหรือปลายปากกาของคุณถูกตั้งค่าให้ดูเป็น iOS 6 การตั้งค่าเดลต้าจะทำให้มุมมองนั้นถูกเลื่อนและ / หรือปรับขนาดตามจำนวนเดลต้าที่ตั้งไว้เมื่อเรียกใช้ใน iOS 7 อีกทางหนึ่งหากสตอรีบอร์ดหรือปลายปากกาของคุณถูกตั้งค่าให้ดู ใน iOS 7 จากนั้นเดลต้าจะถูกนำไปใช้เมื่อทำงานใน iOS 6
หากคุณใช้ AutoLayout แสดงว่า Delta จะไม่พร้อมใช้งาน ลองสิ่งนี้ (ทดสอบใน iPhone 4s ที่ใช้ iOS6):
- (void) viewWillLayoutSubviews {
//iOS 6 workaround offset
if ([[[UIDevice currentDevice] systemVersion] floatValue] < 7) {
self.view.clipsToBounds = YES;
CGRect screenRect = [[UIScreen mainScreen] bounds];
CGFloat screenHeight = 0.0;
screenHeight = screenRect.size.width;
CGRect screenFrame = CGRectMake(0, -20, self.view.frame.size.width,self.view.frame.size.height+10);
self.view.frame = screenFrame;
}
}