Menjelaskan perbedaan antara secara otomatisAdjustsScrollViewInsets, extendedLayoutIncludeOpaqueBars, edgeForExtendedLayout di iOS7

250

Saya telah membaca banyak tentang transisi iOS7 UI.

Saya tidak bisa mendapatkan apa yang tiga sifat ini automaticallyAdjustsScrollViewInsets, extendedLayoutIncludesOpaqueBars, edgesForExtendedLayout??

Misalnya saya mencoba membuat pengontrol tampilan saya mulai di bawah bilah status tetapi saya tidak dapat mencapainya.

pengguna1010819
sumber
5
dan mengapa Anda berpikir saya belum membaca itu? .. Masalahnya adalah tidak bekerja seperti yang diharapkan seperti pada saya belum mengerti dengan baik !! .. itulah alasannya
user1010819
1
Ohhh, saya salah mengerti apa yang Anda katakan di sana. Saya tidak mencoba terdengar menggurui, hanya saja ketika beberapa orang mengajukan pertanyaan seperti ini, dan baru di situs, mereka kehilangan solusi yang jelas.
erdekhayser
8
Dalam metode viewDidLoad Anda, tambahkan if ([self respondsToSelector: @selector (edgeForExtendedLayout)]) self.edgesForExtendedLayout = UIRectEdgeNone; yang akan memaksa tampilan Anda untuk mulai di bawah bilah status.
Nandha

Jawaban:

629

Mulai di iOS7, pengontrol tampilan menggunakan tata letak layar penuh secara default. Pada saat yang sama, Anda memiliki kontrol lebih besar tentang bagaimana menjabarkan pandangannya, dan itu dilakukan dengan properti-properti itu:

edgeForExtendedLayout

Pada dasarnya, dengan properti ini Anda mengatur sisi mana dari tampilan Anda dapat diperluas untuk mencakup seluruh layar. Bayangkan bahwa Anda mendorong UIViewControllera UINavigationController. Ketika tampilan pengontrol tampilan diletakkan, itu akan mulai di mana bilah navigasi berakhir, tetapi properti ini akan mengatur sisi tampilan mana (atas, kiri, bawah, kanan) dapat diperluas untuk mengisi seluruh layar.

Mari kita lihat dengan sebuah contoh:

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

Di sini Anda tidak mengatur nilai edgesForExtendedLayout, karena itu nilai default diambil ( UIRectEdgeAll), sehingga tampilan memperluas tata letaknya untuk mengisi seluruh layar.

Ini hasilnya:

tanpa tepi untuk tata letak yang diperluas, tampilan memenuhi seluruh layar

Seperti yang Anda lihat, latar belakang merah memanjang di belakang bilah navigasi dan bilah status.

Sekarang, Anda akan mengatur nilai itu UIRectEdgeNone, jadi Anda memberi tahu pengontrol tampilan untuk tidak memperluas tampilan untuk menutupi layar:

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

Dan hasilnya:

dengan set edgeForExtendedLayout, tampilan berada tepat di bawah navigasi


secara otomatisAdjustsScrollViewInsets

Properti ini digunakan saat tampilan Anda UIScrollViewmirip atau mirip, seperti a UITableView. Anda ingin meja Anda mulai di mana bilah navigasi berakhir, karena Anda tidak akan melihat seluruh konten jika tidak, tetapi pada saat yang sama Anda ingin meja Anda untuk menutupi seluruh layar saat menggulir. Dalam hal ini, pengaturan edgesForExtendedLayoutke Tidak ada tidak akan berhasil karena meja Anda akan mulai menggulir di mana bilah navigasi berakhir dan itu tidak akan pergi di belakangnya.

Di sinilah properti ini sangat berguna, jika Anda membiarkan pengontrol tampilan secara otomatis menyesuaikan inset (mengatur properti ini ke YA, juga nilai default) itu akan menambahkan insets ke bagian atas tabel, sehingga tabel akan mulai di mana navigasi bilah berakhir, tetapi gulir akan menutupi seluruh layar.

Saat ini diatur ke TIDAK:

tabel akan menggulir ke seluruh layar, tetapi mulai sebagian tertutup

Dan YA (secara default):

tabel bergulir di atas seluruh layar, dan mulai tepat di bawah navigasi

Dalam kedua kasus, tabel bergulir di belakang bilah navigasi, tetapi dalam kasus kedua (YA), itu akan mulai dari bawah bilah navigasi.


extendedLayoutIncludeOpaqueBars

Nilai ini hanyalah tambahan dari yang sebelumnya. Secara default, parameter ini diatur ke NO. Jika status bar buram, pandangan tidak akan diperluas untuk mencakup status bar, bahkan jika Anda memperpanjang tampilan Anda untuk menutupi itu ( edgesForExtendedLayoutuntuk UIRectEdgeAll).

Jika Anda menetapkan nilai ke YA, ini akan memungkinkan tampilan untuk pergi di bawah bilah status lagi.

Jika ada sesuatu yang tidak jelas, tulis komentar dan saya akan menjawabnya.

Bagaimana iOS mengetahui UIScrollView apa yang akan digunakan?

iOS meraih subview pertama dalam tampilan ViewController Anda, yang ada di indeks 0, dan jika itu adalah subkelas UIScrollViewmaka berlaku properti yang dijelaskan untuk itu.

Tentu saja, ini berarti itu UITableViewControllerberfungsi secara default (karena UITableViewini adalah tampilan pertama).

Antonio MG
sumber
Kita perlu mengatur properti ini hanya jika, kita menunjukkan bilah navigasi default, dan bukan jika bilah navigasi yang disesuaikan, kan?
Hemang
1
Tidak, jika Anda menggunakan bilah navigasi iOS tetapi dengan desain Anda sendiri, Anda harus menggunakan properti yang sama. Jika Anda hanya membuat bilah navigasi Anda dari awal, maka properti itu tidak akan berfungsi.
Antonio MG
Saya tidak mengerti mengapa ada lapisan kehitaman kecil di seluruh tampilan? Tolong bantu? : /
aZtraL-EnForceR
24
Penjelasan ini jauh lebih baik daripada Panduan Transisi UI 7 iOS. Ini seharusnya hanya menggantikan panduan, yang tidak masuk akal bagi saya.
Sam
2
Saya pikir extendedLayoutIncludesOpaqueBars harus YA secara default, bukan TIDAK. Mengubah warna tampilan (tembus cahaya) tidak akan memengaruhi tata letak.
Vladimír Slavík
15

Tidak yakin apakah Anda menggunakan storyboard, tetapi jika ya, untuk membuat pengontrol tampilan Anda mulai di bawah bilah status (dan di atas bilah bawah):

Pilih pengontrol tampilan di IB, Pada inspektur atribut, batalkan pilihan 'Extend Edges - Under Top Bars' dan 'Extend Edges - Under Bottom Bars'.

Ali Beadle
sumber
BAIK. Maka saya pikir apa yang disarankan Nandha di atas akan mencapai hasil yang sama secara terprogram. Jika tidak berfungsi di bawah viewDidLoad, mungkin perlu dipindahkan ke viewDidLayoutSubviews.
Ali Beadle
Menunjukkan apakah atau tidak tata letak yang diperluas mencakup bilah buram. @property (nonatomic, assign) BOOL extendedLayoutIncludesOpaqueBars Discussion Nilai defaultnya adalah NO.
Abdul Yasin
+1, Anda memberi saya petunjuk untuk check in Storyboard. Dan saya menyelesaikan sebagian dari masalah saya.
selva
10

Saya menggunakan storyboard dan menggunakan saran di atas berhasil tetapi saya tidak yakin bagaimana cara mengimplementasikannya. Di bawah ini adalah contoh singkat tentang cara mengatasi masalah dengan menempatkan solusi yang disarankan ke dalam 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.
  }

}

Masalah Saya: Penyesuaian Otomatis disetel ke true secara default menyebabkan perbedaan antara desain storyboard dan simulator Penyesuaian Otomatis disetel ke true secara default menyebabkan perbedaan antara desain storyboard dan simulator

Diselesaikan: Kode di atas diterapkan, mematikan penyesuaian otomatis. Kode di atas diterapkan, mematikan penyesuaian otomatis.

Christopher Wade Cantley
sumber
5
jika Anda mengaktifkan secara otomatisAdjustsScrollViewInsets sebagai YA, Anda harus mengatur batasan atas untuk superview bukan topGuideLayout.
xmkevinchen
5

Saya memecahkan masalah ini dengan menambahkan baris ini, tetapi masalah saya terkait dengan UIView, bukanUIScrollView

self.navigationController.navigationBar.translucent = NO;
pengguna3430340
sumber
2

Hanya perlu diingat bahwa automaticallyAdjustsScrollViewInsets properti hanya berfungsi jika beberapa jenis tampilan gulir (tampilan tabel, tampilan koleksi, ...) adalah salah satunya

  • Tampilan VC, atau
  • Subview pertama dari pandangan ini

Lainnya menyarankan, bahwa itu berfungsi bahkan jika itu adalah subview pertama, tetapi ada tampilan gulir lain dalam hierarki tampilan.

EDIT (ekstensi DIY)

Jika Anda menginginkan perilaku serupa walaupun Anda tidak dapat memenuhi persyaratan ini (misalnya Anda memiliki gambar latar belakang di bawah tampilan gulir), Anda dapat menyesuaikan insets tampilan gulir secara manual. Tapi tolong jangan mengaturnya menjadi konstan seperti 44 atau 64 atau bahkan 20 seperti yang banyak disarankan di sekitar SO. Anda tidak bisa mengetahui ukurannya. Mungkin ada pemberitahuan incall / gps / audio, bilah navigasi tidak harus selalu 44 poin dll.

Saya pikir solusi terbaik adalah dengan menggunakan layoutGuide lengthdi didLayoutSubviews:

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

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

Anda dapat menggunakan bottomLayoutGuide dengan cara yang sama.

Vojta Rujbr
sumber
Dan jelas bilah navigasi transparan.
Vojta Rujbr