Giải thích sự khác biệt giữa tự độngAdAdScScViewViewInsets, ExtendedLayoutIncludesOpaqueBars, edgeForExtendsLayout trong iOS7


250

Tôi đã đọc rất nhiều về quá trình chuyển đổi giao diện người dùng iOS7.

Tôi không thể có được những gì ba đặc tính này automaticallyAdjustsScrollViewInsets, extendedLayoutIncludesOpaqueBars, edgesForExtendedLayout??

Ví dụ: tôi đang cố gắng làm cho bộ điều khiển xem của mình bắt đầu bên dưới thanh trạng thái nhưng tôi không thể đạt được nó.


5
và tại sao bạn nghĩ tôi chưa đọc nó? .. Vấn đề là nó không hoạt động như mong đợi vì tôi chưa hiểu rõ về nó !! .. đó là lý do
user1010819

1
Ohhh tôi đã hiểu nhầm những gì bạn đang nói ở đó. Tôi đã không cố gắng để bảo trợ âm thanh, chỉ là khi một số người đặt câu hỏi như thế này và là người mới đối với trang web, họ bỏ lỡ các giải pháp rõ ràng.
erdekhayser

8
Trong phương thức viewDidLoad của bạn, hãy thêm if ([self responssToSelector: @selector (edgeForExtendsLayout)]) self.edgesForExtendsLayout = UIRectEdgeNone; sẽ buộc chế độ xem của bạn bắt đầu bên dưới thanh trạng thái.
Nandha

Câu trả lời:


629

Bắt đầu từ iOS7, các bộ điều khiển xem sử dụng bố cục toàn màn hình theo mặc định. Đồng thời, bạn có nhiều quyền kiểm soát hơn về cách nó đưa ra các quan điểm của mình và điều đó được thực hiện với các thuộc tính đó:

edgeForExtendsLayout

Về cơ bản, với thuộc tính này, bạn đặt các mặt của chế độ xem của mình có thể được mở rộng để bao phủ toàn bộ màn hình. Hãy tưởng tượng rằng bạn đẩy a UIViewControllervào UINavigationController. Khi chế độ xem của bộ điều khiển chế độ xem đó được đặt, nó sẽ bắt đầu khi thanh điều hướng kết thúc, nhưng thuộc tính này sẽ đặt các cạnh của chế độ xem (trên, trái, dưới, phải) có thể được mở rộng để lấp đầy toàn bộ màn hình.

Hãy xem nó với một ví dụ:

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

Ở đây bạn không đặt giá trị của edgesForExtendedLayout, do đó, giá trị mặc định được lấy ( UIRectEdgeAll), vì vậy chế độ xem mở rộng bố cục của nó để lấp đầy toàn bộ màn hình.

Đây là kết quả:

không có cạnh để bố trí mở rộng, chế độ xem sẽ lấp đầy toàn bộ màn hình

Như bạn có thể thấy, nền đỏ kéo dài phía sau thanh điều hướng và thanh trạng thái.

Bây giờ, bạn sẽ đặt giá trị đó thành UIRectEdgeNone, vì vậy bạn đang nói với bộ điều khiển chế độ xem không mở rộng chế độ xem để che màn hình:

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

Và kết quả:

với thiết lập edgeForExtendsLayout, chế độ xem nằm dưới điều hướng


tự độngAdjustScrollViewInsets

Thuộc tính này được sử dụng khi chế độ xem của bạn là UIScrollViewhoặc tương tự, như a UITableView. Bạn muốn bảng của bạn bắt đầu khi thanh điều hướng kết thúc, bởi vì bạn sẽ không nhìn thấy toàn bộ nội dung nếu không, nhưng đồng thời bạn muốn bảng của bạn bao phủ toàn bộ màn hình khi cuộn. Trong trường hợp đó, cài đặt edgesForExtendedLayoutthành Không sẽ không hoạt động vì bảng của bạn sẽ bắt đầu cuộn khi thanh điều hướng kết thúc và nó sẽ không đi phía sau nó.

Đây là nơi mà thuộc tính này có ích, nếu bạn để bộ điều khiển xem tự động điều chỉnh các phần tử (đặt thuộc tính này thành CÓ, cũng là giá trị mặc định), nó sẽ thêm các phần tử vào đầu bảng, do đó bảng sẽ bắt đầu nơi điều hướng thanh kết thúc, nhưng cuộn sẽ bao phủ toàn bộ màn hình.

Đây là khi được đặt thành NO:

bảng sẽ cuộn trên toàn bộ màn hình, nhưng bắt đầu phủ một phần

Và CÓ (theo mặc định):

bảng cuộn trên toàn màn hình và bắt đầu ngay dưới điều hướng

Trong cả hai trường hợp, bảng cuộn phía sau thanh điều hướng, nhưng trong trường hợp thứ hai (CÓ), nó sẽ bắt đầu từ bên dưới thanh điều hướng.


ExtendedLayoutIncludesOpaqueBars

Giá trị này chỉ là một bổ sung cho những cái trước đó. Theo mặc định, tham số này được đặt thành NO. Nếu thanh trạng thái mờ đục, các chế độ xem sẽ không được mở rộng để bao gồm thanh trạng thái, ngay cả khi bạn mở rộng chế độ xem của mình để che nó ( edgesForExtendedLayoutsang UIRectEdgeAll).

Nếu bạn đặt giá trị thành CÓ, điều này sẽ cho phép chế độ xem bên dưới thanh trạng thái một lần nữa.

Nếu có gì đó không rõ ràng, hãy viết bình luận và tôi sẽ trả lời nó.

Làm thế nào để iOS biết UIScrollView sẽ sử dụng cái gì?

iOS lấy lượt xem đầu tiên trong chế độ xem của ViewContoder, khung nhìn ở chỉ số 0 và nếu đó là lớp con của UIScrollViewthì áp dụng các thuộc tính được giải thích cho nó.

Tất nhiên, điều này có nghĩa là UITableViewControllerhoạt động theo mặc định (vì đây UITableViewlà chế độ xem đầu tiên).


Chúng ta chỉ cần đặt thuộc tính này nếu, chúng tôi đang hiển thị thanh điều hướng mặc định, chứ không phải nếu thanh điều hướng tùy chỉnh của nó, phải không?
Hemang

1
Không, nếu bạn sử dụng thanh điều hướng iOS nhưng với thiết kế của riêng bạn, bạn sẽ cần sử dụng các thuộc tính tương tự. Nếu bạn chỉ tạo thanh điều hướng của mình bằng đầu, thì các thuộc tính đó sẽ không hoạt động.
Antonio MG

Tôi không hiểu tại sao lại xuất hiện một lớp đen nhỏ trên toàn bộ khung nhìn? Xin vui lòng giúp đỡ? : /
aZtraL-EnForceR

24
Giải thích này tốt hơn nhiều so với Hướng dẫn chuyển đổi giao diện người dùng iOS 7. Điều này chỉ nên thay thế hướng dẫn, mà không có ý nghĩa với tôi.
Sam

2
Tôi nghĩ mặc địnhLayoutIncludesOpaqueBars nên CÓ theo mặc định thay vì KHÔNG. Thay đổi màu sắc xem (độ mờ) sẽ không ảnh hưởng đến bố cục.
Vladimír Slavík

15

Không chắc chắn nếu bạn đang sử dụng bảng phân cảnh, nhưng nếu có, để làm cho bộ điều khiển chế độ xem của bạn bắt đầu bên dưới thanh trạng thái (và phía trên thanh dưới cùng):

Chọn bộ điều khiển chế độ xem trong IB, Trong trình kiểm tra thuộc tính, bỏ chọn 'Mở rộng các cạnh - Dưới các thanh trên cùng' và 'Mở rộng các cạnh - Dưới các thanh dưới cùng'.


ĐỒNG Ý. Sau đó, tôi nghĩ rằng những gì Nandha đề xuất ở trên sẽ đạt được kết quả tương tự theo chương trình. Nếu nó không hoạt động dưới viewDidLoad, nó có thể cần được chuyển đến viewDidLayoutSubview.
Ali Beadle

Cho biết liệu bố trí mở rộng có bao gồm các thanh mờ hay không. @property (nonatomic, gán) BOOL ExtendedLayoutIncludesOpaqueBars Thảo luận Giá trị mặc định là NO.
Abdul Yasin

+1, Bạn đã cho tôi một gợi ý để kiểm tra Storyboard. Và tôi đã giải quyết được một nửa vấn đề của mình.
selva

10

Tôi đang sử dụng bảng phân cảnh và sử dụng lời khuyên ở trên có hiệu quả tuy nhiên tôi không chắc chắn chính xác cách thực hiện. Dưới đây là một ví dụ ngắn về cách giải quyết vấn đề bằng cách đưa giải pháp được đề xuất vào ViewContoder.

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

}

Vấn đề của tôi: Điều chỉnh tự động được đặt thành đúng theo mặc định gây ra sự khác biệt giữa thiết kế bảng phân cảnh và trình giả lập Điều chỉnh tự động được đặt thành đúng theo mặc định gây ra sự khác biệt giữa thiết kế bảng phân cảnh và trình giả lập

Đã giải quyết: Mã ở trên được áp dụng, tắt điều chỉnh tự động. Mã ở trên áp dụng, tắt điều chỉnh tự động.


5
nếu bạn bật tự độngAdAdScScViewViewInsets là CÓ, bạn nên đặt ràng buộc hàng đầu thành giám sát chứ không phải topGuideLayout.
xmkevinchen

5

Tôi đã giải quyết vấn đề này bằng cách thêm dòng này, nhưng vấn đề của tôi liên quan đến một UIView, không phảiUIScrollView

self.navigationController.navigationBar.translucent = NO;

2

Chỉ cần lưu ý rằng thuộc automaticallyAdjustsScrollViewInsets tính chỉ hoạt động nếu một loại chế độ xem cuộn (chế độ xem bảng, chế độ xem bộ sưu tập, ...) là

  • Quan điểm của VC, hoặc
  • Subview đầu tiên của quan điểm này

Một đề xuất khác, rằng nó hoạt động tốt nhất ngay cả khi đó là lần xem đầu tiên, nhưng có các chế độ xem cuộn khác trong hệ thống phân cấp chế độ xem.

EDIT (phần mở rộng DIY)

Nếu bạn muốn có hành vi tương tự ngay cả khi bạn không thể đáp ứng các điều kiện này (ví dụ: bạn có hình nền bên dưới chế độ xem cuộn), bạn có thể điều chỉnh các chế độ xem cuộn theo cách thủ công. Nhưng vui lòng không đặt nó thành hằng số như 44 hoặc 64 hoặc thậm chí 20 như nhiều đề xuất xung quanh SO. Bạn không thể biết kích thước bao giờ. Có thể có thông báo incall / gps / audio, thanh điều hướng không phải luôn luôn là 44 điểm, v.v.

Tôi nghĩ giải pháp tốt nhất là sử dụng layoutGuide lengthtrong didLayoutSubview:

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

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

Bạn có thể sử dụng bottomLayoutGuide theo cách tương tự.


Và rõ ràng thanh điều hướng là mờ.
Vojta Rujbr
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.