การอธิบายความแตกต่างระหว่างการปรับอัตโนมัติ ScrollViewInsets, ขยายเลย์เอาต์รวมแถบโอเปร่า, ขอบสำหรับขยายขยายเค้าโครงใน iOS7


250

ฉันอ่านมากเกี่ยวกับการเปลี่ยนแปลง UI ของ iOS7

ผมไม่สามารถที่จะได้รับสิ่งที่ทั้งสามคุณสมบัติautomaticallyAdjustsScrollViewInsets, extendedLayoutIncludesOpaqueBars, edgesForExtendedLayout??

ตัวอย่างเช่นฉันพยายามทำให้ตัวควบคุมมุมมองของฉันเริ่มต้นที่ด้านล่างของแถบสถานะ แต่ฉันไม่สามารถทำมันได้


5
และทำไมคุณถึงคิดว่าฉันยังไม่ได้อ่านนั่น .. ปัญหาคือว่าใช้งานไม่ได้ตามที่คาดไว้ในขณะที่ฉันไม่เข้าใจดี !! .. นั่นคือเหตุผล
user1010819

1
โอ้ฉันเข้าใจผิดที่คุณพูดอยู่ที่นั่น ฉันไม่ได้พยายามทำให้อุปถัมภ์มันเป็นเพียงว่าเมื่อบางคนถามคำถามเช่นนี้และยังใหม่กับเว็บไซต์พวกเขาคิดถึงวิธีแก้ปัญหาที่ชัดเจน
erdekhayser

8
ในเมธอด viewDidLoad ของคุณให้เพิ่มถ้า ([self responsesToSelector: @selector (edgeForExtendedLayout)]) self.edgesForExtendedLayout = UIRectEdgeNone; ซึ่งจะบังคับให้มุมมองของคุณเริ่มต้นด้านล่างแถบสถานะ
Nandha

คำตอบ:


629

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

edgesForExtendedLayout

โดยพื้นฐานแล้วด้วยคุณสมบัตินี้คุณสามารถกำหนดให้มุมมองด้านใดของคุณสามารถขยายให้ครอบคลุมทั้งหน้าจอได้ ลองนึกภาพว่าคุณดันUIViewControllerเข้าไปUINavigationControllerเป็นเมื่อวางมุมมองของตัวควบคุมมุมมองนั้นมันจะเริ่มต้นที่แถบนำทางสิ้นสุดลง แต่คุณสมบัตินี้จะตั้งค่าที่ด้านข้างของมุมมอง (ด้านบนซ้ายด้านล่างขวา) สามารถขยายให้เต็มหน้าจอได้

ลองดูด้วยตัวอย่าง:

UIViewController *viewController = [[UIViewController alloc] init];
viewController.view.backgroundColor = [UIColor redColor];
UINavigationController *mainNavigationController = [[UINavigationController alloc] initWithRootViewController:viewController];

ที่นี่คุณไม่ได้ตั้งค่าเป็นedgesForExtendedLayoutดังนั้นจึงมีการใช้ค่าเริ่มต้น ( UIRectEdgeAll) ดังนั้นมุมมองจะขยายเค้าโครงเพื่อเติมเต็มหน้าจอทั้งหมด

นี่คือผลลัพธ์ที่ได้:

โดยไม่มีขอบสำหรับโครงร่างเพิ่มเติมมุมมองเติมทั้งหน้าจอ

อย่างที่คุณเห็นพื้นหลังสีแดงจะขยายด้านหลังของแถบนำทางและแถบสถานะ

ตอนนี้คุณกำลังจะตั้งค่าUIRectEdgeNoneดังกล่าวเป็นดังนั้นคุณจึงบอกให้คอนโทรลเลอร์มุมมองไม่ขยายมุมมองให้ครอบคลุมหน้าจอ:

UIViewController *viewController = [[UIViewController alloc] init];
viewController.view.backgroundColor = [UIColor redColor];
viewController.edgesForExtendedLayout = UIRectEdgeNone;
UINavigationController *mainNavigationController = [[UINavigationController alloc] initWithRootViewController:viewController];

และผลลัพธ์:

ด้วย edgeForExtendedLayout set มุมมองอยู่ภายใต้การนำทาง


automaticallyAdjustsScrollViewInsets

คุณสมบัตินี้จะใช้เมื่อมุมมองของคุณเป็นหรือคล้ายกันเช่นUIScrollView UITableViewคุณต้องการให้ตารางของคุณเริ่มต้นที่แถบนำทางสิ้นสุดลงเพราะคุณจะไม่เห็นเนื้อหาทั้งหมดหากไม่ได้ แต่ในเวลาเดียวกันคุณต้องการให้ตารางของคุณครอบคลุมทั้งหน้าจอเมื่อเลื่อน ในกรณีดังกล่าวการตั้งค่าedgesForExtendedLayoutเป็นไม่มีจะไม่ทำงานเนื่องจากตารางของคุณจะเริ่มเลื่อนตำแหน่งที่แถบนำทางสิ้นสุดลงและจะไม่ไปทางด้านหลัง

นี่คือที่ที่คุณสมบัตินี้มีประโยชน์ถ้าคุณให้ตัวควบคุมมุมมองปรับ insets โดยอัตโนมัติ (ตั้งค่าคุณสมบัตินี้เป็น YES ด้วยค่าเริ่มต้น) มันจะเพิ่มส่วนแทรกเข้าไปที่ด้านบนของตารางดังนั้นตารางจะเริ่มต้นที่การนำทาง แถบสิ้นสุด แต่การเลื่อนจะครอบคลุมทั้งหน้าจอ

นี่คือเมื่อตั้งค่าเป็นไม่:

ตารางจะเลื่อนไปตามหน้าจอทั้งหมด แต่จะครอบคลุมบางส่วน

และใช่ (โดยค่าเริ่มต้น):

ตารางเลื่อนบนหน้าจอทั้งหมดและเริ่มต้นภายใต้การนำทาง

ในทั้งสองกรณีตารางจะเลื่อนด้านหลังแถบนำทาง แต่ในกรณีที่สอง (YES) ตารางจะเริ่มจากด้านล่างแถบนำทาง


extendedLayoutIncludesOpaqueBars

ค่านี้เป็นส่วนเพิ่มเติมจากค่าก่อนหน้า โดยดีฟอลต์พารามิเตอร์นี้ถูกตั้งค่าเป็น NO หากแถบสถานะทึบแสงมุมมองจะไม่ถูกขยายเพื่อรวมแถบสถานะแม้ว่าคุณจะขยายมุมมองของคุณเพื่อให้ครอบคลุม ( edgesForExtendedLayoutถึงUIRectEdgeAll)

หากคุณตั้งค่าเป็น YES สิ่งนี้จะทำให้มุมมองไปอยู่ใต้แถบสถานะอีกครั้ง

หากบางสิ่งไม่ชัดเจนเขียนความคิดเห็นและฉันจะตอบ

iOS รู้ได้อย่างไรว่า UIScrollView ใช้อะไร

iOS คว้ามุมมองย่อยแรกในมุมมองของคุณ ViewController อันที่ดัชนี 0 และถ้ามันเป็นประเภทย่อยของUIScrollViewแล้วใช้คุณสมบัติอธิบายกับมัน

แน่นอนนี่หมายความว่าใช้UITableViewControllerงานได้ตามค่าเริ่มต้น (เนื่องจากUITableViewเป็นมุมมองแรก)


เราจำเป็นต้องตั้งค่าคุณสมบัตินี้เฉพาะเมื่อเรากำลังแสดงแถบการนำทางเริ่มต้นและไม่ใช่ถ้าแถบนำทางที่กำหนดเองใช่ไหม
Hemang

1
ไม่ถ้าคุณใช้แถบการนำทาง iOS แต่ด้วยการออกแบบของคุณเองคุณจะต้องใช้คุณสมบัติเดียวกัน หากคุณเพิ่งสร้างแถบนำทางโดยเริ่มต้นคุณสมบัตินั้นจะไม่ทำงาน
Antonio MG

ฉันไม่เข้าใจว่าทำไมมีเลเยอร์สีดำเล็ก ๆ ปกคลุมทั่วทั้งมุมมอง? กรุณาช่วย? : /
aZtraL-EnForceR

24
คำอธิบายนี้ดีกว่าคู่มือการเปลี่ยน iOS 7 UI อย่างมาก นี่ควรเปลี่ยนแนวทางซึ่งไม่สมเหตุสมผลสำหรับฉัน
Sam

2
ฉันคิดว่า ExtendedLayoutIncludesOpaqueBars ควรเป็น YES เป็นค่าเริ่มต้นแทนที่จะไม่ใช่ การเปลี่ยนสีมุมมอง (ความโปร่งแสง) ไม่ควรส่งผลต่อเค้าโครง
VladimírSlavík

15

ไม่แน่ใจว่าคุณกำลังใช้สตอรีบอร์ดหรือไม่หากคุณต้องการให้ตัวควบคุมมุมมองของคุณเริ่มต้นด้านล่างแถบสถานะ (และเหนือแถบด้านล่าง):

เลือกตัวควบคุมมุมมองใน IB ในตัวตรวจสอบแอตทริบิวต์ให้ยกเลิกการเลือก 'ขยายขอบ - ใต้แถบด้านบน' และ 'ขยายขอบ - ใต้แถบล่าง'


ตกลง. จากนั้นฉันคิดว่าสิ่งที่ Nandha แนะนำไว้ข้างต้นจะบรรลุผลลัพธ์เดียวกันโดยทางโปรแกรม หากไม่ทำงานภายใต้ viewDidLoad อาจต้องย้ายไปที่ viewDidLayoutSubviews
Ali Beadle

ระบุว่าโครงร่างแบบขยายรวมถึงแถบทึบแสงหรือไม่ @property (ไม่ใช่เชิงอะตอม, มอบหมาย) BOOL ExtendedLayoutIncludesOpaqueBars การสนทนาค่าเริ่มต้นคือ NO
Abdul Yasin

+1, คุณให้คำแนะนำแก่ฉันเพื่อเช็คอินสตอรีบอร์ด และฉันได้แก้ปัญหาครึ่งหนึ่งของฉันแล้ว
selva

10

ฉันใช้สตอรีบอร์ดและใช้คำแนะนำข้างต้นแล้ว แต่ก็ไม่แน่ใจว่าจะใช้งานอย่างไร ด้านล่างนี้เป็นตัวอย่างสั้น ๆ เกี่ยวกับวิธีแก้ไขปัญหาโดยการใส่โซลูชันที่แนะนำไว้ใน ViewController

import Foundation
import UIKit

// This ViewController is connected to a view on a storyboard that 
// has a scrolling sub view.
class TheViewController: UIViewController {

  // Prepares the view prior to loading.  Putting it in viewDidAppear didn't work.
  override func viewWillAppear(animated: Bool) {

    // this method is an extension of the UIViewController 
    // so using self works as you might expect.
    self.automaticallyAdjustsScrollViewInsets = false

    // Default is "true" so this sets it to false tells it to use 
    // the storyboard as you have it placed
    // and not how it thinks it should place it.
  }

}

ปัญหาของฉัน: ตั้งค่าการปรับอัตโนมัติเป็นจริงโดยค่าเริ่มต้นทำให้เกิดความแตกต่างระหว่างการออกแบบสตอรีบอร์ดและเครื่องจำลอง ตั้งค่าปรับอัตโนมัติเป็นจริงโดยค่าเริ่มต้นทำให้เกิดความแตกต่างระหว่างการออกแบบสตอรีบอร์ดและเครื่องจำลอง

แก้ไขแล้ว: ใช้รหัสด้านบนปิดการปรับอัตโนมัติ ใช้รหัสด้านบนปิดการปรับอัตโนมัติ


5
หากคุณเปิดใช้งาน AutomaticAdjustsScrollViewInsets เป็น YES คุณควรกำหนดข้อ จำกัด ด้านบนให้เป็น superview ไม่ใช่ topGuideLayout
xmkevinchen

5

ฉันแก้ไขปัญหานี้ด้วยการเพิ่มบรรทัดนี้ แต่ปัญหาของฉันเกี่ยวข้องกับ a UIViewไม่ใช่UIScrollView

self.navigationController.navigationBar.translucent = NO;

2

อย่าลืมว่า automaticallyAdjustsScrollViewInsets คุณสมบัติจะใช้งานได้ก็ต่อเมื่อมีมุมมองแบบเลื่อน (มุมมองตาราง, มุมมองแบบสะสม, ... ) บางอย่าง

  • มุมมองของ VC หรือ
  • มุมมองย่อยแรกของมุมมองนี้

อื่น ๆ แนะนำว่ามันทำงานได้แม้ว่ามันจะเป็นมุมมองย่อยแรก แต่มีมุมมองเลื่อนอื่น ๆ ในลำดับชั้นมุมมอง

แก้ไข (ต่อขยาย DIY)

หากคุณต้องการพฤติกรรมที่คล้ายกันแม้ว่าคุณจะไม่สามารถปฏิบัติตามเงื่อนไขเหล่านี้ได้ (เช่นคุณมีภาพพื้นหลังด้านล่างมุมมองแบบเลื่อน) คุณสามารถปรับมุมมองแบบเลื่อนได้ด้วยตนเอง แต่โปรดอย่าตั้งค่าเป็นค่าคงที่เช่น 44 หรือ 64 หรือแม้กระทั่ง 20 เช่นเดียวกับที่หลายคนแนะนำให้ใช้ คุณไม่สามารถรู้ขนาดได้ อาจมีการแจ้งเตือน incall / gps / audio แถบการนำทางไม่จำเป็นต้องมี 44 pts เป็นต้น

ฉันคิดว่าทางออกที่ดีที่สุดคือการใช้ layoutGuide lengthใน didLayoutSubviews:

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    scrollView.contentInset = UIEdgeInsets(top: topLayoutGuide.length, left: 0, bottom: 0, right: 0)
    scrollView.scrollIndicatorInsets = scrollView.contentInset
}

คุณสามารถใช้ bottomLayoutGuide ในวิธีเดียวกัน


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