Adakah yang tahu bagaimana saya bisa menggunakan subclass kustom saya UINavigationBar
jika saya instantiate secara UINavigationController
terprogram (tanpa IB)?
Seret UINavigationController
di IB tunjukkan saya di bawah Bilah Navigasi dan menggunakan Identity Inspectory saya dapat mengubah jenis kelas dan mengatur subkelas saya sendiri UINavigationBar
tetapi secara terprogram saya tidak bisa, navigationBar
properti Pengontrol Navigasi hanya-baca ...
Apa yang harus saya lakukan untuk menyesuaikan bilah navigasi secara terprogram? Apakah IB lebih "kuat" daripada "kode"? Saya percaya semua yang bisa dilakukan di IB bisa dilakukan juga secara terprogram.
Jawaban:
Anda tidak perlu membuang-buang waktu dengan XIB, cukup gunakan KVC.
sumber
Sejak iOS5, apple menyediakan metode untuk melakukan ini secara langsung. Referensi
sumber
Mulai iOS 4, Anda dapat menggunakan
UINib
kelas tersebut untuk membantu memecahkan masalah ini.UINavigationBar
subclass kustom Anda .UINavigationController
sebagai objek tunggal.UINavigationController
'sUINavigationBar
untuk subclass kustom Anda.[navController setViewcontrollers[NSArray arrayWithObject:myRootVC]];
[navController pushViewController:myRootVC];
Dalam kode:
Sekarang Anda sudah memiliki
UINavigationController
kebiasaan AndaUINavigationBar
.sumber
Sejauh yang saya tahu, terkadang memang perlu untuk membuat subclass UINavigationBar, untuk melakukan beberapa pengaturan ulang gaya yang tidak standar. Terkadang mungkin untuk menghindari keharusan melakukannya dengan menggunakan kategori , tetapi tidak selalu.
Saat ini, sejauh yang saya tahu, satu - satunya cara untuk menyetel UINavigationBar khusus dalam UIViewController adalah melalui IB (yaitu, melalui arsip) - mungkin seharusnya tidak seperti itu, tetapi untuk saat ini, kita harus menerimanya.
Ini sering kali baik-baik saja, tetapi terkadang menggunakan IB tidak terlalu memungkinkan.
Jadi, saya melihat tiga opsi:
Opsi 1 tidak layak (atau setidaknya terlalu menjengkelkan) bagi saya dalam hal ini, karena saya perlu membuat UINavigationController secara terprogram, 2 sedikit berbahaya dan lebih merupakan opsi terakhir menurut saya, jadi saya memilih opsi 3.
Pendekatan saya adalah membuat arsip 'template' dari UINavigationController, dan membatalkan pengarsipannya, mengembalikannya ke dalam
initWithRootViewController
.Begini caranya:
Dalam IB, saya membuat UINavigationController dengan kelas yang sesuai untuk UINavigationBar.
Kemudian, saya mengambil pengontrol yang ada, dan menyimpan salinan yang diarsipkan menggunakan
+[NSKeyedArchiver archiveRootObject:toFile:]
. Saya baru saja melakukan ini di dalam delegasi aplikasi, di simulator.Saya kemudian menggunakan utilitas 'xxd' dengan flag -i, untuk menghasilkan kode c dari file yang disimpan, untuk menyematkan versi yang diarsipkan di subclass saya (
xxd -i path/to/file
).Di dalam
initWithRootViewController
saya membatalkan pengarsipan template itu, dan mengatur diri ke hasil dari pengarsipan:Kemudian, saya bisa mengambil contoh baru dari subkelas UIViewController saya yang memiliki bilah navigasi khusus:
Ini memberi saya modal UITableViewController dengan bilah navigasi dan bilah alat yang sudah disiapkan, dan dengan kelas bilah navigasi khusus di tempatnya. Saya tidak perlu melakukan penggantian metode yang sedikit menjengkelkan, dan saya tidak perlu mengotak-atik nib ketika saya benar-benar hanya ingin bekerja secara terprogram.
Saya ingin melihat padanan
+layerClass
dalam UINavigationController -+navigationBarClass
- tetapi untuk saat ini, ini berfungsi.sumber
Saya menggunakan "opsi 1"
Buat file nib hanya dengan UINavigationController di dalamnya. Dan atur Kelas UINavigationBar ke Kelas kustom saya.
sumber
Solusi Michael berfungsi, tetapi Anda dapat menghindari NSKeyedArchiver dan utilitas 'xxd'. Cukup Subclass UINavigationController dan timpa
initWithRootViewController
, memuat NIB NavigationController kustom Anda secara langsung:sumber
Memperbarui: Menggunakan
object_SetClass()
tidak lagi berfungsi seolah-olah iOS5 GM. Solusi alternatif telah ditambahkan di bawah.Gunakan NSKeyedUnarchiver untuk secara manual menyetel kelas pembatalan pengarsipan untuk bilah navigasi.
Catatan: Solusi asli ini hanya berfungsi sebelum iOS5:
Ada solusi hebat, yang saya posting di sini - menyuntikkan subkelas navBar langsung ke tampilan Anda
UINavigationController
:sumber
Satu skenario yang saya temukan bahwa kita perlu menggunakan subclass daripada kategori adalah mengatur warna latar belakang navigationbar dengan gambar pola, karena di iOS5 menimpa drawRect menggunakan kategori tidak berfungsi lagi. Jika Anda ingin mendukung ios3.1-5.0, satu-satunya cara yang dapat Anda lakukan adalah dengan subclass navigationbar.
sumber
Metode kategori ini berbahaya dan bukan untuk pemula. Selain itu, kerumitan dengan iOS4 dan iOS5 yang berbeda, menjadikan area ini dapat menyebabkan bug bagi banyak orang. Berikut adalah subclass sederhana yang saya gunakan yang mendukung iOS4.0 ~ iOS6.0 dan sangat sederhana.
.h
.m
sumber
Tidak disarankan untuk membuat subkelas
UINavigationBar
kelas. Cara yang disukai untuk menyesuaikan bilah navigasi adalah dengan mengatur propertinya agar muncul seperti yang Anda inginkan dan menggunakan tampilan khusus di dalam UIBarButtonItems bersama dengan delegasi untuk mendapatkan perilaku yang diinginkan.Apa yang Anda coba lakukan yang membutuhkan subclass?
Juga, menurut saya IB tidak benar-benar menggantikan bilah navigasi. Saya cukup yakin itu tidak menampilkan yang default dan memiliki bilah navigasi kustom Anda sebagai subview. Jika Anda memanggil UINavigationController.navigationBar, apakah Anda mendapatkan instance dari bilah Anda?
sumber
Jika Anda ingin membuat subclass navBar hanya untuk mengubah gambar latar belakang - tidak perlu di iOS 5. Akan ada metode seperti ini setBackgroundImage
sumber
setBackgroundImage:forBarMetrics:
seperti yang dijelaskan di sini: developer.apple.com/library/IOS/#documentation/UIKit/Reference/…Selanjutnya untuk komentar obb64, saya akhirnya menggunakan triknya dengan
setViewControllers:animated:
mengatur pengontrol sebagairootController
untuknavigationController
dimuat dari nib. Inilah kode yang saya gunakan:sumber