Oh man, ini membuat saya sakit kepala selama beberapa hari dan tidak tahu bagaimana melakukan ini. Bagian terburuknya adalah membuat proyek Xcode iOS baru dengan templat detail induk bekerja dengan baik. Untungnya, pada akhirnya, fakta kecil itu adalah bagaimana saya menemukan solusinya.
Ada beberapa posting yang saya temukan yang menyarankan bahwa solusinya adalah mengimplementasikan primaryViewControllerForCollapsingSplitViewController:
metode baru UISplitViewControllerDelegate
. Saya mencoba itu tidak berhasil. Apa yang dilakukan Apple dalam templat master-detail yang tampaknya berfungsi adalah mengimplementasikan splitViewController:collapseSecondaryViewController:ontoPrimaryViewController:
metode pendelegasian yang baru (tarik napas dalam-dalam untuk semua ini) (lagi aktif UISplitViewControllerDelegate
). Menurut dokumen , metode ini:
Minta delegasi untuk menyesuaikan pengontrol tampilan primer dan untuk memasukkan pengontrol tampilan sekunder ke dalam antarmuka yang diciutkan.
Pastikan untuk membaca bagian diskusi dari metode itu untuk perincian yang lebih spesifik.
Cara Apple menangani ini adalah:
- (BOOL)splitViewController:(UISplitViewController *)splitViewController
collapseSecondaryViewController:(UIViewController *)secondaryViewController
ontoPrimaryViewController:(UIViewController *)primaryViewController {
if ([secondaryViewController isKindOfClass:[UINavigationController class]]
&& [[(UINavigationController *)secondaryViewController topViewController] isKindOfClass:[DetailViewController class]]
&& ([(DetailViewController *)[(UINavigationController *)secondaryViewController topViewController] detailItem] == nil)) {
// Return YES to indicate that we have handled the collapse by doing nothing; the secondary controller will be discarded.
return YES;
} else {
return NO;
}
}
Implementasi ini pada dasarnya melakukan hal berikut:
- Jika
secondaryViewController
apa yang kami harapkan (a UINavigationController
), dan itu menunjukkan apa yang kami harapkan (a DetailViewController
- pengontrol tampilan Anda), tetapi tidak memiliki model ( detailItem
), maka " Return YES to indicate that we have handled the collapse by doing nothing; the secondary controller will be discarded.
"
- Jika tidak, kembalilah "
NO
untuk membiarkan pengontrol tampilan terpisah mencoba dan menggabungkan konten pengontrol tampilan sekunder ke dalam antarmuka yang diciutkan"
Hasilnya adalah sebagai berikut untuk iPhone dalam potret (baik mulai dalam potret atau memutar ke potret - atau lebih tepatnya kelas ukuran kompak):
- Jika pandangan Anda benar
- dan memiliki model, tampilkan pengendali tampilan detail
- tetapi tidak memiliki model, tunjukkan pengontrol tampilan master
- Jika pandangan Anda salah
- tampilkan pengontrol tampilan master
Jelas seperti lumpur.
UISplitViewController
dan selalu kembaliYES
dari metode itu, lalu hanya mengubah kelas tampilan terpisah di Storyboard, karena saya selalu ingin menunjukkan master pada iPhone dalam potret. :)UISplitViewController
tetapi ternyata itu tidak berhasil:splitViewController:collapseSecondaryViewController:ontoPrimaryViewController:
tidak pernah dipanggil. Alih-alih, saya menyalin template Apple dan meletakkannya di AppDelagate. Ini mengharuskan beberapa perubahan untuk membuat UISplitViewControllerapplication didFinishLaunchingWithOptions:
juga (di mana saya juga menyalin templat Apple).splitViewController:collapseSecondaryViewController:ontoPrimaryViewController:
tidak pernah dipanggil. Tampaknya delegasi sedang mengaturapplicationDidFinishLaunchingWithOptions:
metode delegasi aplikasi saya dengan benar . Adakah orang lain yang melihat masalah ini dan BUKAN solusi ini berfungsi?Inilah jawaban yang diterima di Swift. Cukup buat subkelas ini dan tetapkan ke splitViewController Anda di storyboard Anda.
sumber
func splitViewController(_ splitViewController: UISplitViewController, collapseSecondary secondaryViewController: UIViewController, onto primaryViewController: UIViewController) -> Bool {
Versi cepat jawaban Mark S yang benar
Seperti yang disediakan oleh templat Master-Detail Apple.
Klarifikasi
(Apa yang Mark S katakan agak membingungkan)
Metode delegasi ini disebut
splitViewController: collapseSecondaryViewController: ontoPrimaryViewController:
, karena memang itulah fungsinya. Saat mengubah ke ukuran lebar yang lebih ringkas (misalnya saat memutar telepon dari landscape ke portrait), ia perlu mengecilkan pengontrol tampilan terbagi menjadi hanya satu di antaranya.Fungsi ini mengembalikan boolean untuk memutuskan apakah harus menutup Detail dan menunjukkan Master atau tidak.
Jadi dalam kasus kami, kami akan memutuskan berdasarkan apakah ada detail yang dipilih atau tidak. Bagaimana kita tahu jika detail kita dipilih? Jika kita mengikuti templat Master-Detail Apple, pengontrol tampilan detail harus memiliki variabel opsional yang memiliki info detail, jadi jika nihil (.Tidak), belum ada yang dipilih dan kami harus memperlihatkan Master sehingga pengguna dapat memilih sesuatu.
Itu dia.
sumber
Apple's Master-Detail template
, itu tidak dimaksudkan untuk menjadi hebat atau ringkas, hanya faktual. :)Dari dokumentasi , Anda perlu menggunakan delegasi untuk memberi tahu agar
UISplitViewController
tidak memasukkan tampilan detail ke dalam "antarmuka runtuh" (yaitu "mode Potret" dalam kasing Anda). Di Swift 4, metode delegasi untuk menerapkan untuk yang telah diubah namanya:sumber
.m:
sumber
Aplikasi saya ditulis dalam Swift 2.x dan bisa berjalan dengan baik. Setelah mengubahnya menjadi Swift 3.0 (menggunakan XCode converter), ia mulai menampilkan detail terlebih dahulu alih-alih master dalam mode potret. Masalahnya adalah nama fungsi splitViewController tidak berubah agar sesuai dengan yang baru dari UISplitViewControllerDelegate.
Setelah mengubah nama fungsi itu secara manual, aplikasi saya sekarang dapat berfungsi dengan benar:
sumber
self.delegate = self
padaviewDidLoad
metode.Jika Anda tidak memiliki nilai default untuk ditampilkan di controller tampilan detail, Anda bisa menghapus segue default antara SplitViewController dan UIViewController detail Anda di story board. Ini akan membuatnya selalu masuk ke Master View Controller terlebih dahulu.
Efek sampingnya adalah alih-alih melihat dua tampilan dalam lanskap, Anda akan melihat satu tampilan dalam ukuran penuh di SplitViewController hingga Show Detail Segue di master view controller diaktifkan.
sumber
Untuk semua orang yang tidak dapat menemukan bagian friday cs193p:
Di Swift 3.1.1 membuat subclass dari UISplitViewController dan mengimplementasikan salah satu metode pendelegasiannya bekerja untuk saya seperti pesona:
Papan cerita saya
sumber
public func splitViewController(_ splitViewController: UISplitViewController, collapseSecondary secondaryViewController: UIViewController, onto primaryViewController: UIViewController) -> Bool
Menurut pendapat saya, Anda harus menyelesaikan masalah ini lebih umum. Anda dapat subkelas UISplitViewController dan mengimplementasikan protokol di pengontrol tampilan tertanam.
Contoh implementasi di UITableViewController:
Semoga ini bisa membantu. Jadi Anda bisa menggunakan kembali kelas ini dan hanya perlu mengimplementasikan protokol.
sumber
Hapus saja DetailViewController dari pengontrol SplitView saat Anda memerlukannya untuk memulai dari Master.
sumber
Ini bekerja untuk saya di iOS-11 dan Swift 4:
sumber
Fungsi ini diganti namanya dalam versi baru Swift, jadi kode ini berfungsi pada Swift 4:
sumber
Solusi Xamarin / C #
sumber
Cukup atur
preferredDisplayMode
propertiUISplitViewController
ke.allVisible
sumber