Bilah status dan bilah navigasi muncul di atas batas tampilan saya di iOS 7

435

Baru-baru ini saya mengunduh Xcode 5 DP untuk menguji aplikasi saya di iOS 7. Hal pertama yang saya perhatikan dan konfirmasi adalah bahwa batas tampilan saya tidak selalu diubah ukurannya menjadi akun untuk bilah status dan bilah navigasi.

Di viewDidLayoutSubviews, saya mencetak batas tampilan:

{{0, 0}, {320, 568}}

Ini menghasilkan konten saya yang muncul di bawah bilah navigasi dan bilah status.

Saya tahu saya bisa memperhitungkan ketinggian sendiri dengan mendapatkan ketinggian layar utama, mengurangi ketinggian bilah status dan tinggi bilah navigasi, tapi itu sepertinya pekerjaan tambahan yang tidak perlu.

Bagaimana saya bisa memperbaiki masalah ini?

Memperbarui:

Saya telah menemukan solusi untuk masalah khusus ini. Setel properti tembus bilah navigasi ke NO:

self.navigationController.navigationBar.translucent = NO;

Ini akan memperbaiki tampilan agar tidak dibingkai di bawah bilah navigasi dan bilah status.

Namun, saya belum menemukan perbaikan untuk kasus ini ketika Anda ingin bilah navigasi menjadi tembus. Sebagai contoh, melihat foto layar penuh, saya ingin memiliki panel navigasi transparan, dan tampilan yang akan dibingkai di bawahnya. Itu bekerja, tetapi ketika saya beralih menampilkan / menyembunyikan bilah navigasi, saya telah mengalami hasil yang lebih aneh. Subview pertama (a UIScrollView) mendapatkan batasannya y asalnya berubah setiap kali.

Beebcon
sumber
Saya juga mendapatkan masalah yang sama di xcode 5 DP
Gopesh Gupta
Beri tahu saya jika Anda akan mendapatkan solusi
Gopesh Gupta
1
Lihat di bilah navigasi untuk properti warna tint, Anda harus dapat mengubah warna biru itu menjadi apa pun yang Anda inginkan.
beebcon
9
Saya benci upgrade ios kadang-kadang karena Apple tidak pernah memberi Anda kesempatan untuk menjaga aplikasi Anda tetap kompatibel.
Bagusflyer
3
Jika masalah terkait dengan tampilan di bawah bilah status setelah menyembunyikan bilah pengontrol navigasi saya akan merujuk jawaban oleh @Stunner stackoverflow.com/a/18976660/235206 sebagai solusinya
MiKL

Jawaban:

495

Anda dapat mencapai ini dengan menerapkan properti baru yang disebut edgesForExtendedLayoutdi iOS7 SDK. Silakan tambahkan kode berikut untuk mencapai ini,

if ([self respondsToSelector:@selector(edgesForExtendedLayout)])
        self.edgesForExtendedLayout = UIRectEdgeNone;

Anda perlu menambahkan hal di atas dalam -(void)viewDidLoadmetode Anda .

iOS 7 membawa beberapa perubahan pada bagaimana Anda mengatur dan menyesuaikan tampilan UI . Perubahan tata letak pengontrol tampilan, warna warna, dan font mempengaruhi semua objek UIKit di aplikasi Anda. Selain itu, penyempurnaan API pengenal gerakan memberi Anda kontrol yang lebih baik atas interaksi gerakan.

Menggunakan View Controllers

Di iOS 7, pengendali tampilan menggunakan tata letak layar penuh. Pada saat yang sama, iOS 7 memberi Anda lebih banyak kontrol granular atas cara pengontrol tampilan menjabarkan pandangannya. Secara khusus, konsep tata letak layar penuh telah disempurnakan untuk membiarkan pengontrol tampilan menentukan tata letak setiap tepi tampilan.

Properti wantsFullScreenLayoutview controller sudah tidak digunakan lagi di iOS 7. Jika saat ini Anda menentukanwantsFullScreenLayout = NO , controller tampilan dapat menampilkan kontennya di lokasi layar yang tidak terduga ketika dijalankan di iOS 7.

Untuk menyesuaikan cara pengontrol tampilan menjabarkan pandangannya, UIViewController sediakan properti berikut:

  • edgeForExtendedLayout

The edgesForExtendedLayoutproperti menggunakan UIRectEdgejenis, yang menentukan masing-masing persegi panjang empat tepi, selain tak dan semua menentukan. Gunakan edgesForExtendedLayoutuntuk menentukan tepi mana dari tampilan yang harus diperluas, terlepas dari bar transparan. Secara default, nilai properti ini adalah UIRectEdgeAll.

  • extendedLayoutIncludesOpaqueBars

Jika desain Anda menggunakan bilah buram, sempurnakan edgesForExtendedLayoutdengan juga menyetel extendedLayoutIncludesOpaqueBarsproperti ke NO . (Nilai default extendedLayoutIncludesOpaqueBarsadalah NO .)

  • secara otomatisAdjustsScrollViewInsets

Jika Anda tidak ingin inset konten tampilan gulir disesuaikan secara otomatis, atur automaticallyAdjustsScrollViewInsetske NO . (Nilai default automaticallyAdjustsScrollViewInsetsadalah YA .)

  • topLayoutGuide, bottomLayoutGuide

The topLayoutGuidedan bottomLayoutGuideproperti menunjukkan lokasi tepi bar atas atau bawah dalam tampilan pengontrol tampilan. Jika bilah harus tumpang tindih bagian atas atau bawah tampilan, Anda dapat menggunakan Interface Builder untuk memposisikan tampilan relatif terhadap bar dengan membuat kendala di bagian bawah topLayoutGuideatau ke bagian bawahLayoutGuide. (Jika tidak ada bar yang tumpang tindih dengan tampilan, bagian bawah topLayoutGuidesama dengan bagian atas tampilan dan bagian atas bottomLayoutGuidesama dengan bagian bawah tampilan.) Kedua properti dibuat dengan malas saat diminta.

Silakan lihat, apple doc

Nandha
sumber
2
Itu tidak akan dikompilasi di bawah iOS6. Saya pikir itu harus ditulis sebagai performselector ...
Shmidt
8
Ya, itulah mengapa saya menyertakan pemilih untuk memeriksa dengan syarat, jika ([jawab sendiri untuk pemilih: @selektor (edgeForExtendedLayout)])
Nandha
19
Ini tidak akan berfungsi jika saya tidak memiliki bilah navigasi. Dalam hal ini, pandangan saya meluas di belakang bilah status ..
Van Du Tran
4
Saya memiliki masalah yang sama dengan @VanDuTran. edgeForExtendedLayout tidak membantu jika bilah navigasi disembunyikan.
fishinear
6
itu bekerja tetapi ... tidak ada efek tembus lagi ... bagaimana kita bisa menjaga efek tembus juga ...
Dipu Rajak
110

Anda tidak perlu menghitung seberapa jauh untuk menggeser semuanya, ada properti build untuk ini. Di Pembuat Antarmuka, sorot pengontrol tampilan Anda, lalu navigasikan ke inspektur atribut. Di sini Anda akan melihat beberapa kotak centang di sebelah kata "Extend Edges". Seperti yang Anda lihat, pada tangkapan layar pertama, pilihan default adalah konten muncul di bawah bilah atas dan bawah, tetapi tidak di bawah bilah buram, itulah sebabnya pengaturan gaya bilah agar tidak tembus bekerja untuk Anda.

Seperti yang dapat Anda lihat pada tangkapan layar pertama, ada dua elemen UI yang bersembunyi di bawah bilah navigasi. (Saya telah mengaktifkan wireframes di IB untuk menggambarkan hal ini) Elemen-elemen ini, sebuah UIButton dan UISegmentedControl keduanya memiliki asal "y" yang diatur ke nol, dan pengontrol tampilan diatur untuk memungkinkan konten di bawah bilah atas.

masukkan deskripsi gambar di sini

Tangkapan layar kedua ini menunjukkan apa yang terjadi ketika Anda membatalkan centang pada kotak "Di Bawah Bilah Atas". Seperti yang Anda lihat, tampilan pengontrol tampilan telah digeser ke bawah dengan tepat agar asalnya berada tepat di bawah bilah navigasi.

masukkan deskripsi gambar di sini

Ini juga dapat dicapai secara terprogram melalui penggunaan -[UIViewController edgesForExtendedLayout]. Berikut ini tautan ke referensi kelas untuk edgeForExtendedLayout , dan untuk UIRectEdge

[self setEdgesForExtendedLayout:UIRectEdgeNone];
Mick MacCallum
sumber
15
Bagaimana saya melakukan hal yang sama untuk hanya melihat dalam .xib?
bobik
2
Saya menambahkan satu label pada tampilan dan saya mengikuti instruksi Anda tetapi ini tidak berfungsi untuk saya
RMRAHUL
5
@ robot Jawaban untuk pertanyaan XIB adalah, "Anda tidak bisa." Lagipula tidak melalui IB. Ajukan radar dan berharap Apple akhirnya mengatasinya.
memmons
Terima kasih @ 0x7fffffff, Ini hanya info yang saya cari dan sangat membantu.
campo
33

Saya membuat tampilan saya secara terprogram dan ini akhirnya berhasil untuk saya:

- (void) viewDidLayoutSubviews {
    // only works for iOS 7+
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
        CGRect viewBounds = self.view.bounds;
        CGFloat topBarOffset = self.topLayoutGuide.length;

        // snaps the view under the status bar (iOS 6 style)
        viewBounds.origin.y = topBarOffset * -1;

        // shrink the bounds of your view to compensate for the offset
        viewBounds.size.height = viewBounds.size.height + (topBarOffset * -1);
        self.view.bounds = viewBounds;
    }
}

Sumber (di bagian topLayoutGuide di bagian bawah hal.39).

Stunner
sumber
Akhirnya menemukan jawaban yang benar-benar berfungsi untuk ini. Kerja bagus!
StuartM
1
Untuk mengatasi masalah di mana tampilan pengontrol tampilan muncul di bawah bilah status saat bilah navigasi disembunyikan, ini adalah kode yang mengambil tampilan di bawah bilah status.
MiKL
Catatan: ini akan mendorong bagian bawah tampilan Anda dari layar.
memmons
1
Juga, kecuali jika Anda sedang membangun untuk hanya iOS7, kode di atas akan melemparkan kesalahan - topLayoutGuideadalah iOS7 saja.
memmons
1
Juga perhatikan bahwa ketika tampilan utama Anda adalah UITableView, viewDidLayoutSubviews akan dipanggil pada setiap gulir. UITableView Anda akan diperkecil hingga ketinggiannya 15px. Tambahkan bendera untuk hanya menjalankan kode ini satu kali. ;)
Thomas Johannesmeyer
30

Solusi Swift 3 / Swift 4 yang juga berfungsi dengan file NIB / XIB di iOS 10+:

override func viewDidLoad() {
    super.viewDidLoad()

    edgesForExtendedLayout = []
}
flo_23
sumber
Inilah yang Membantu saya ... Sangat Sederhana. Terima kasih :-)
Hernan Arber
Terima kasih ini sangat membantu
Muhammad Ahmed Baig
Ini adalah solusi terbaik untuk 10.x Swift 3+ IMO
shokaveli
10

Jika Anda ingin tampilan memiliki bilah nav transparan (yang agak menyenangkan) Anda harus mengatur contentInset atau yang serupa.

Inilah cara saya melakukannya:

// Check if we are running on ios7
if([[[[UIDevice currentDevice] systemVersion] componentsSeparatedByString:@"."][0] intValue] >= 7) {
      CGRect statusBarViewRect = [[UIApplication sharedApplication] statusBarFrame];
      float heightPadding = statusBarViewRect.size.height+self.navigationController.navigationBar.frame.size.height;

      myContentView.contentInset = UIEdgeInsetsMake(heightPadding, 0.0, 0.0, 0.0);
}
Magnus
sumber
3
mengapa Anda tidak dapat langsung membandingkannya dengan 7,0
Leena
1
lol Saya mengerti: memeriksa versi tertentu dengan tambahan minor kurang kuat. Tetapi Anda memeriksa apakah nilainya lebih BESAR atau sama dengan membandingkan dengan 7,0 akan baik-baik saja di sini;)
EeKay
1
@leena - Ini adalah fitur dalam 7.x dan yang lebih baru - jadi saya memeriksa apakah versinya 7 atau lebih besar dan melewatkan revisi minor dalam pemeriksaan.
Magnus
2
Saya Punya masalah dengan tableView saya karena ditampilkan di belakang Tabbar saya. Yang membuat baris terakhir dari meja saya tidak pernah menggulir di atas Tabbar. Saya memperbaikinya seperti itu: myTableView.contentInset = UIEdgeInsetsMake (0, 0,0, TabbarHeight, 0)
James Laurenstin
contentInsetadalah properti dari UIScrollView. Bagaimana jika tampilan utama saya bukan subkelas dari UIScrollView. Lalu bagaimana saya memperbaiki masalah yang tumpang tindih?
Pwner
9

edgesForExtendedLayoutmelakukan trik untuk iOS 7. Namun, jika Anda membangun aplikasi di iOS 7 SDK dan menyebarkannya di iOS 6, bilah navigasi tampak transparan dan pandangan di bawahnya. Jadi, untuk memperbaikinya untuk iOS 7 maupun untuk iOS 6 lakukan ini:

self.navigationController.navigationBar.barStyle = UIBarStyleBlackOpaque;
if ([self respondsToSelector:@selector(edgesForExtendedLayout)])
    self.edgesForExtendedLayout = UIRectEdgeNone;   // iOS 7 specific
Raj Pawan Gumdal
sumber
9

Di file aplikasi plist Anda tambahkan satu baris, sebut saja "Lihat tampilan bilah status berbasis-pengontrol" dan setel ke NO .

Idan
sumber
7

Trik paling sederhana adalah membuka file NIB dan melakukan dua langkah sederhana ini:

  1. Cukup aktifkan dan atur sesuai keinginan:

Masukkan deskripsi gambar di sini

  1. Pilih UIView's / UIIMageView's / ... yang ingin Anda turunkan. Dalam kasus saya hanya logo yang tumpang tindih dan saya telah mengatur delta ke +15; (ATAU -15 jika Anda memilih iOS 7 pada langkah 1)

Masukkan deskripsi gambar di sini

Dan hasilnya :

Sebelum Setelah

Riskov
sumber
6
Ini bekerja, tetapi ini terlihat seperti solusi yang sulit dipertahankan. Akan lebih baik untuk memperbaiki masalah daripada menambalnya.
NLemay
akan lebih baik untuk melakukannya secara terprogram untuk subview semua tampilan karena tidak berfungsi jika diterapkan pada tampilan utama
wildmonkey
5

Solusi Cepat:

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)
    self.edgesForExtendedLayout = UIRectEdge.None
}
fatihyildizhan
sumber
4
Sekarang ini adalah edgeForExtendedLayout = []
Leon
1
Karena ini adalah jawaban publik, kita tidak boleh lupa untuk menelepon:super.viewWillAppear(animated)
prodos
4

Saya ingin memperluas jawaban Stunner, dan menambahkan ifpernyataan untuk memeriksa apakah itu iOS-7, karena ketika saya mengujinya di iOS 6 aplikasi saya akan macet.

Penambahan akan menambahkan:

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0)

Jadi saya sarankan menambahkan metode ini ke MyViewControler.mfile Anda :

- (void) viewDidLayoutSubviews {
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
        CGRect viewBounds = self.view.bounds;
        CGFloat topBarOffset = self.topLayoutGuide.length;
        viewBounds.origin.y = topBarOffset * -1;
        self.view.bounds = viewBounds;
    }
}
werdsackjon
sumber
4

Cepat 3

override func viewWillAppear(_ animated: Bool) {
    self.edgesForExtendedLayout = []
}
Shahrukh
sumber
3

Saya memiliki skenario di mana saya menggunakan BannerViewController yang ditulis oleh Apple untuk menampilkan iklan saya dan ScrollViewController yang tertanam dalam BannerViewController.

Untuk mencegah bilah navigasi menyembunyikan konten saya, saya harus membuat dua perubahan.

1) Ubah BannerViewController.m

- (void)viewDidLoad
{
   [super viewDidLoad];
   float systemVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
   if (systemVersion >= 7.0) {
      self.edgesForExtendedLayout = UIRectEdgeNone;
   }
}

2) Ubah ScrollViewContoller saya

- (void)viewDidLoad
{
    [super viewDidLoad];
    float systemVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
    if (systemVersion >= 7.0) {
        self.edgesForExtendedLayout = UIRectEdgeBottom;
    }
}

Sekarang iklan ditampilkan dengan benar di bagian bawah tampilan alih-alih ditutupi oleh bilah Navigasi dan konten di atas tidak terpotong.

Xavier John
sumber
2

cukup atur kode berikut ini dalam tampilan akan muncul.

  if ([[[UIDevice currentDevice] systemVersion] floatValue]<= 7) {
self.edgesForExtendedLayout = UIRectEdgeNone;
 }
Amit Shelgaonkar
sumber
Ini adalah satu-satunya hal yang berhasil dalam keadaan saya.
goobliata
2

buat batasan untuk Top Layout seperti ini masukkan deskripsi gambar di sini

carmen_munich
sumber
2

Swift 4.2 - Xcode 10.0 - iOS 12.0:

if #available(iOS 11.0, *) {} else {
  self.edgesForExtendedLayout = []
  self.navigationController?.view.backgroundColor = .white
}
juliancadi
sumber
1

Bagi saya, solusi paling sederhana adalah menambahkan dua kunci ke dalam plist

masukkan deskripsi gambar di sini

giuseppe
sumber
+1, saya memiliki "Status bar awalnya disembunyikan" = YA, tetapi ketika menambahkan "Lihat tampilan status bar berbasis pengontrol" = TIDAK Saya menyingkirkan bilah status.
Jonas Byström
1

Tambahkan kunci "Lihat tampilan bilah status berbasis Kontroler" dari dropdownlist sebagai baris dalam info.plist. Sesuatu seperti ini:

Masukkan deskripsi gambar di sini

Kursat Turkay
sumber
interesting.it membantu proyek cocos2d saya. ketika saya mengaktifkan opsi ini, saya dapat melihat bilah status teratas benar-benar telah hilang atau muncul.
Kursat Turkay
1

Saya memiliki masalah yang sama dengan aplikasi saya dengan iPads (armv7, armv7s, amr64) hanya dengan menghadirkan UIViewController lain dan setelah memberhentikan mereka pergi nav bar di bawah status bar ... Saya menghabiskan banyak waktu untuk menemukan solusi untuk itu. Saya menggunakan storyboard dan di InterfaceBuilder untuk UIViewController yang membuat saya mengatur Presentasi dari FullScreen -> Konteks Saat Ini dan itu memperbaiki masalah ini. Ini berfungsi di aplikasi saya hanya untuk iPads => iOS8.0 (pengujian dengan iOS8.1) dan untuk iPad dengan iOS 7.1 tidak berfungsi !!lihat tangkapan layar

Alexej W.
sumber
Dalam kasus saya, tampilan utama saya tumpang tindih tabBar saya dan saya tidak tahu mengapa. Ternyata Extend Edges> Under Bottom Bars sudah dicentang. Sangat sulit untuk melihatnya karena latar belakang aplikasi saya berwarna putih dan hanya menghasilkan beberapa tingkat opacity di atas TabBar saya. Terima kasih!
Jesus Rodriguez
0

Langkah-langkah Untuk Menyembunyikan bilah status di iOS 7:

1. Buka file info.plist aplikasi Anda.

2.Dan Atur, Lihat tampilan status berbasis pengontrol: Boolean NO

Semoga saya memecahkan masalah status bar .....

chandrika
sumber
0

Dalam kasus saya memuat loadView () terputus
kode ini: self.edgesForExtendedLayout = UIRectEdgeNone

tapi setelah menghapus loadView () semuanya bekerja dengan baik

DevB2F
sumber