Saya mencoba melakukan sesuatu yang sedikit rumit, tetapi sesuatu yang seharusnya mungkin. Jadi di sini adalah tantangan untuk semua ahli di luar sana (forum ini adalah paket dari kalian semua :)).
Saya sedang membuat "komponen" Kuisioner, yang ingin saya muat di NavigationContoller
(saya QuestionManagerViewController
). "Komponen" adalah "kosong" UIViewController
, yang dapat memuat pandangan yang berbeda tergantung pada pertanyaan yang perlu dijawab.
Cara saya melakukannya adalah:
- Buat objek Question1View sebagai
UIView
subclass, tentukan beberapaIBOutlets
. - Buat (menggunakan Interface Builder) the
Question1View.xib
(DI SINI ADALAH MASALAH SAYA MASALAH ADALAH ). Saya mengatur keduaUIViewController
danUIView
menjadi dari Question1View kelas. - Saya menautkan outlet dengan komponen view (menggunakan IB).
Saya menimpa
initWithNib
sayaQuestionManagerViewController
untuk terlihat seperti ini:- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { if (self = [super initWithNibName:@"Question1View" bundle:nibBundleOrNil]) { // Custom initialization } return self; }
Ketika saya menjalankan kode, saya mendapatkan kesalahan ini:
2009-05-14 15: 05: 37.152 iMobiDines [17148: 20b] *** Mengakhiri aplikasi karena pengecualian yang tidak tertangkap '
NSInternalInconsistencyException
', alasan: '-[UIViewController _loadViewFromNibNamed:bundle:]
memuat nib "Question1View" tetapi tampilan outlet tidak disetel.'
Saya yakin ada cara untuk memuat tampilan menggunakan file nib, tanpa perlu membuat kelas viewController.
sumber
Terima kasih semua. Saya memang menemukan cara untuk melakukan apa yang saya inginkan.
UIView
dengan yangIBOutlet
Anda butuhkan.UIViewController
(Tidak ada subkelas kustom, tetapi yang "asli"). Tampilan Pemilik File terhubung ke tampilan utama dan kelasnya dinyatakan sebagai yang dari langkah 1).IBOutlet
s.The
DynamicViewController
dapat menjalankan logika untuk memutuskan apa melihat / xib ke beban. Setelah membuat keputusan, dalamloadView
metode ini masukkan sesuatu seperti ini:Itu dia!
Metode bundel utama
loadNibNamed
akan mengatur inisialisasi tampilan dan membuat koneksi.Sekarang ViewController dapat menampilkan tampilan atau yang lain tergantung pada data dalam memori, dan layar "induk" tidak perlu repot dengan logika ini.
sumber
Saya tidak yakin apa yang dibicarakan beberapa jawaban, tetapi saya harus meletakkan jawaban ini di sini ketika saya mencari di Google lain kali. Kata kunci: "Cara memuat UIView dari nib" atau "Cara memuat UIView dari NSBundle."
Berikut kode hampir 100% langsung dari buku Apress Beginning iPhone 3 (halaman 247, "Menggunakan Sel Table View Baru"):
Ini mengandaikan Anda memiliki
UIView
subclass yang dipanggilBlah
, sebuah nib yang disebutBlah
yang mengandungUIView
yang kelasnya diatur keBlah
.Kategori: NSObject + LoadFromNib
Ekstensi cepat
Dan contoh yang digunakan:
sumber
isKindOf
Anda dilindungi dari perubahan struktur Bundle.assert
akan mungkin solusi yang lebih baik. Dengan cara ini Anda hanya akan menyembunyikan masalahnya.for
. Itu melengkapi itu.Untuk semua yang perlu mengelola lebih dari satu contoh tampilan khusus, yaitu Koleksi Outlet , saya menggabungkan dan mengkustomisasi jawaban @Gonso, @AVeryDev, dan @Olie dengan cara ini:
Buat custom
MyView : UIView
dan atur sebagai " Custom Class " dari rootUIView
di XIB yang diinginkan ;Buat semua outlet yang Anda butuhkan
MyView
(lakukan sekarang karena setelah poin 3, IB akan menyarankan Anda untuk menghubungkan outlet keUIViewController
dan bukan ke tampilan kustom seperti yang kita inginkan);Tetapkan Anda
UIViewController
sebagai " Pemilik File " dari tampilan kustom XIB ;Di
UIViewController
tambah yang baruUIViews
untuk setiap instance yangMyView
Anda inginkan, dan hubungkan mereka untukUIViewController
membuat Koleksi Outlet : tampilan ini akan bertindak sebagai tampilan "pembungkus" untuk mesin virtual tampilan kustom;Akhirnya, di
viewDidLoad
AndaUIViewController
tambahkan baris berikut:sumber
Saya akan menggunakan UINib untuk membuat UIView khusus untuk digunakan kembali
File yang dibutuhkan dalam kasus ini adalah MyCustomView.xib , MyCustomViewClass.h dan MyCustomViewClass.m Catatan yang
[UINib instantiateWithOwner]
mengembalikan array, jadi Anda harus menggunakan elemen yang mencerminkan UIView yang ingin Anda gunakan kembali. Dalam hal ini elemen pertama.sumber
Anda seharusnya tidak mengatur kelas pengontrol tampilan Anda menjadi subkelas dari
UIView
dalam Interface Builder. Itu pasti paling tidak bagian dari masalah Anda. Biarkan itu sebagai baikUIViewController
, beberapa subkelasnya, atau beberapa kelas khusus yang Anda miliki.Adapun memuat hanya tampilan dari xib, saya berada di bawah asumsi bahwa Anda harus memiliki semacam pengontrol tampilan (bahkan jika itu tidak meluas
UIViewController
, yang mungkin terlalu berat untuk kebutuhan Anda) ditetapkan sebagai Pemilik File di Antarmuka Builder jika Anda ingin menggunakannya untuk mendefinisikan antarmuka Anda. Saya melakukan sedikit riset untuk mengkonfirmasi ini juga. Ini karena jika tidak, tidak akan ada cara untuk mengakses elemen antarmuka diUIView
dalamnya, juga tidak akan ada cara untuk memiliki metode Anda sendiri dalam kode yang dipicu oleh peristiwa.Jika Anda menggunakan
UIViewController
sebagai Pemilik File untuk tampilan Anda, Anda bisa menggunakannyainitWithNibName:bundle:
untuk memuatnya dan mendapatkan objek view controller kembali. Di IB, pastikan Anda mengaturview
outlet ke tampilan dengan antarmuka Anda di xib. Jika Anda menggunakan beberapa jenis lainnya objek sebagai file Anda pemilik, Anda harus menggunakanNSBundle
'sloadNibNamed:owner:options:
metode untuk memuat pena, lewat sebuah contoh dari berkas ini pemilik ke metode. Semua propertinya akan diatur dengan benar sesuai dengan outlet yang Anda tentukan di IB.sumber
Anda juga dapat menggunakan initWithNibName UIViewController alih-alih loadNibNamed. Lebih sederhana, saya menemukan.
Sekarang Anda hanya perlu membuat MySubView.xib dan MySubView.h / m. Di MySubView.xib setel kelas Pemilik File ke UIViewController dan lihat kelas ke MySubView.
Anda dapat menentukan posisi dan ukuran
subview
file induk xib yang digunakan.sumber
Ini adalah pertanyaan yang bagus (+1) dan jawabannya hampir membantu;) Maaf teman-teman, tapi saya punya banyak waktu menghabiskan ini, meskipun Gonso & AVeryDev memberikan petunjuk yang baik. Semoga jawaban ini akan membantu orang lain.
MyVC
adalah view controller yang memegang semua hal ini.MySubview
adalah pandangan yang ingin kita muat dari xibMySubView
yang ukuran & bentuk yang tepat & diposisikan di tempat yang Anda inginkan.Di MyVC.h, miliki
Di MyVC.m,
@synthesize mySubView;
dan jangan lupa untuk melepaskannya didealloc
.UIView *view
(mungkin tidak perlu, tetapi bekerja untuk saya.) Mensintesis & lepaskan di .mMySubview
, dan tautkan properti tampilan ke tampilan Anda.IBOutlet
diinginkanKembali di MyVC.m, miliki
Agak sulit bagi saya adalah: petunjuk di jawaban lain memuat pandangan saya dari xib, tetapi TIDAK mengganti tampilan di MyVC (ya!) - Saya harus menukar itu sendiri.
Juga, untuk mendapatkan akses ke
mySubview
metode,view
properti dalam file .xib harus disetel keMySubview
. Kalau tidak, ia kembali seperti biasaUIView
.Jika ada cara untuk memuat
mySubview
langsung dari xib sendiri, itu akan rock, tapi ini membuat saya di mana saya harus berada.sumber
Ini adalah sesuatu yang seharusnya lebih mudah. Saya akhirnya memperluas
UIViewController
dan menambahkanloadNib:inPlaceholder:
pemilih. Sekarang bisa saya katakanBerikut kode untuk kategorinya (ia menggunakan rigamarole yang sama seperti yang dijelaskan oleh Gonso):
sumber
Dengan cepat
Sebenarnya resolusi saya untuk masalah ini adalah, untuk memuat tampilan dalam viewDidLoad di CustonViewController saya di mana saya ingin menggunakan tampilan seperti itu:
Jangan memuat tampilan dalam suatu
loadView()
metode! Metode loadView berfungsi untuk memuat tampilan untuk ViewController kustom Anda.sumber
Saya juga ingin melakukan hal serupa, inilah yang saya temukan: (SDK 3.1.3)
Saya memiliki view controller A (itu sendiri dimiliki oleh Nav controller) yang memuat VC B pada tombol tekan:
Dalam AViewController.m
Sekarang VC B memiliki antarmuka dari Bnib, tetapi ketika tombol ditekan, saya ingin pergi ke 'mode edit' yang memiliki UI terpisah dari nib yang berbeda, tetapi saya tidak ingin VC baru untuk mode edit, Saya ingin pena baru dikaitkan dengan B VC saya yang ada.
Jadi, dalam BViewController.m (metode tekan tombol)
Kemudian pada tombol lain tekan (untuk keluar dari mode edit):
dan saya kembali ke Bnib asli saya.
Ini berfungsi dengan baik, tetapi perhatikan EditMode.nib saya hanya memiliki 1 obj tingkat atas di dalamnya, sebuah obj UIView. Tidak masalah apakah Pemilik File di nib ini ditetapkan sebagai BViewController atau NSObject default, TAPI pastikan Outlet Outlet di Pemilik File TIDAK diatur ke apa pun. Jika ya, maka saya mendapatkan crash exc_bad_access dan hasil xcode untuk memuat 6677 stack frame yang menunjukkan metode UIView internal yang berulang kali disebut ... sehingga terlihat seperti infinite loop. (View Outlet IS diatur dalam Bnib asli saya)
Semoga ini membantu.
sumber
Saya membuat kategori yang saya sukai:
UIView+NibInitializer.h
UIView+NibInitializer.m
Lalu, panggil seperti ini:
Gunakan nama nib jika nib Anda bernama sesuatu selain nama kelas Anda.
Untuk menimpanya dalam subclass Anda untuk perilaku tambahan, itu bisa terlihat seperti ini:
sumber
Untuk pengguna Swift dengan opsi yang dirancang:
UIView
subkelas khusus dan file xib , yang akan kami beri nama setelah nama kelas kami sendiri: dalam kasus kami MemeView. Di dalam kelas Mim View, ingat untuk mendefinisikannya sebagai dapat dirancang dengan@IBDesignable
atribut sebelum deklarasi kelasPilih untuk mengatur Pemilik File di xib dengan
UIView
subkelas kustom kami di panel Inspektur IndetityDalam file xib sekarang kita dapat membangun antarmuka kita, membuat batasan, membuat outlet, tindakan, dll.
Kita perlu mengimplementasikan beberapa metode ke kelas kustom kita untuk membuka xib setelah diinisialisasi
class XibbedView: UIView {
}
Di kelas khusus kami, kami juga dapat mendefinisikan beberapa properti yang dapat diinspirasikan untuk memiliki kontrol penuh atas mereka dari pembangun antarmuka
@IBDesignable class MemeView: XibbedView {
}
Beberapa contoh:
Jika kita perlu menambahkan lebih banyak informasi view saat ditampilkan di dalam storyboard atau xib lainnya, untuk melakukan itu kita bisa mengimplementasikan
prepareForInterfaceBuilder()
, metode ini hanya akan dieksekusi ketika membuka file di interface builder. Jika Anda melakukan semua yang saya tulis tetapi tidak ada yang berfungsi, itu adalah cara untuk men-debug tampilan sigle dengan menambahkan breakpoints dalam implementasinya. Berikut adalah hierarki tampilan.Semoga ini dapat membantu contoh lengkap dapat diunduh di sini
sumber
let nib = loadNib(nibName)
ini adalah instance XibbedView, jika Anda memanggil `` `addSubview (nib)` `` maka Anda menambahkan satu instance XibbedView ke instance XibbedView lainnya?Saya menemukan posting blog ini oleh Aaron Hillegass (penulis, instruktur, Cocoa ninja) sangat mencerahkan. Bahkan jika Anda tidak mengadopsi pendekatannya yang dimodifikasi untuk memuat file NIB melalui penginisialisasi yang ditunjuk Anda mungkin setidaknya akan mendapatkan pemahaman yang lebih baik dari proses yang terjadi. Saya telah menggunakan metode ini akhir-akhir ini untuk sukses besar!
sumber
Jawaban sebelumnya tidak memperhitungkan perubahan dalam struktur NIB (XIB) yang terjadi antara 2.0 dan 2.1 pada iPhone SDK. Konten pengguna sekarang mulai dari indeks 0 bukannya 1.
Anda dapat menggunakan makro 2.1 yang valid untuk semua versi 2.1 dan di atasnya (dua garis bawah sebelum IPHONE:
Kami menggunakan teknik yang mirip dengan ini untuk sebagian besar aplikasi kami.
Barney
sumber
Saya punya alasan untuk melakukan hal yang sama (secara program memuat tampilan dari file XIB), tetapi saya perlu melakukan ini sepenuhnya dari konteks subkelas dari subkelas a
UIView
(yaitu tanpa melibatkan pengontrol tampilan dengan cara apa pun). Untuk melakukan ini, saya membuat metode utilitas ini:Lalu saya menyebutnya dari
initWithFrame
metode subclass saya seperti:Diposting untuk kepentingan umum; jika ada yang melihat masalah tanpa melakukannya dengan cara ini, beri tahu saya.
sumber
Berikut cara untuk melakukannya di Swift (saat ini sedang menulis Swift 2.0 di XCode 7 beta 5).
Dari
UIView
subkelas Anda yang Anda tetapkan sebagai "Kelas Kustom" di Interface Builder buat metode seperti ini (subkelas saya disebut RecordingFooterView):Maka Anda bisa menyebutnya seperti ini:
let recordingFooterView = RecordingFooterView.loadFromNib()
sumber
Tidak ada jawaban yang menjelaskan cara membuat XIB yang berdiri sendiri yang merupakan akar dari pertanyaan ini. Tidak ada
Xcode 4
opsi untuk "Buat File XIB Baru".Untuk melakukan ini
Ini mungkin tampak sederhana tetapi dapat menghemat waktu Anda beberapa menit untuk itu karena kata "XIB" tidak muncul di mana pun.
sumber
@AVeryDev
6) Untuk melampirkan tampilan yang dimuat ke tampilan pengontrol tampilan Anda:
Agaknya, perlu untuk menghapusnya dari tampilan untuk menghindari kebocoran memori.
Untuk memperjelas: pengontrol tampilan memiliki beberapa IBOutlets, beberapa di antaranya terhubung ke item dalam file nib asli (seperti biasa), dan beberapa terhubung ke item dalam nib yang dimuat. Kedua nib memiliki kelas pemilik yang sama. Tampilan yang dimuat menutupi yang asli.
Petunjuk: atur opacity dari tampilan utama di nib yang dimuat ke nol, maka itu tidak akan mengaburkan item dari nib asli.
sumber
Setelah menghabiskan banyak waktu, saya mencari solusi berikut. Ikuti langkah-langkah ini untuk membuat custom
UIView
.1) Buat kelas myCustomView diwarisi dari UIView .
2) Buat .xib dengan nama myCustomView .
3) Ubah Kelas UIView di dalam file .xib Anda, tetapkan Kelas myCustomView di sana.
4) Buat IBOutlets
5) Muat .xib dalam myCustomView * customView . Gunakan kode contoh berikut.
sumber
Versi terpendek:
sumber
Saya memiliki konvensi penamaan xibs dengan view di dalamnya sama dengan view. Sama seperti yang akan dilakukan pengontrol tampilan. Kemudian, saya tidak perlu menuliskan nama kelas dalam kode. Saya memuat UIView dari file nib dengan nama yang sama.
Contoh untuk kelas yang disebut MyView.
Dalam kode Anda, buat MyView baru seperti ini:
MyView * myView = [MyView nib_viewFromNibWithOwner: owner];
Inilah kategori untuk ini:
Saya kemudian akan memasang tombol dengan tindakan dari controller yang saya gunakan, dan mengatur hal-hal pada label menggunakan outlet di subkelas tampilan kustom saya.
sumber
Untuk memuat tampilan dari nib / xib di Swift 4 secara terprogram:
sumber
Saya akhirnya menambahkan kategori ke UIView untuk ini:
penjelasan di sini: viewcontroller kurang memuat view di ios & mac
sumber