Contoh minimal yang dapat direproduksi (Xcode 11.2 beta, ini berfungsi di Xcode 11.1):
struct Parent: View {
var body: some View {
NavigationView {
Text("Hello World")
.navigationBarItems(
trailing: NavigationLink(destination: Child(), label: { Text("Next") })
)
}
}
}
struct Child: View {
@Environment(\.presentationMode) var presentation
var body: some View {
Text("Hello, World!")
.navigationBarItems(
leading: Button(
action: {
self.presentation.wrappedValue.dismiss()
},
label: { Text("Back") }
)
)
}
}
struct ContentView: View {
var body: some View {
Parent()
}
}
Masalahnya tampaknya terletak pada menempatkan NavigationLink
bagian dalam saya dari navigationBarItems
pengubah yang bersarang di dalam tampilan SwiftUI yang tampilan root-nya adalah a NavigationView
. Laporan kerusakan menunjukkan bahwa saya mencoba untuk pop ke controller tampilan yang tidak ada ketika saya menavigasi ke depan Child
dan kemudian kembali ke Parent
.
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Tried to pop to a view controller that doesn't exist.'
*** First throw call stack:
Jika saya sebaliknya menempatkan itu NavigationLink
di tubuh tampilan seperti di bawah ini, itu berfungsi dengan baik.
struct Parent: View {
var body: some View {
NavigationView {
NavigationLink(destination: Child(), label: { Text("Next") })
}
}
}
Apakah ini bug SwiftUI atau perilaku yang diharapkan?
EDIT: Saya telah membuka masalah dengan Apple dalam asisten umpan balik mereka dengan ID FB7423964
jika ada orang di luar sana dari Apple yang peduli untuk menimbang :).
EDIT: Tiket terbuka saya di asisten umpan balik menunjukkan ada 10+ masalah yang dilaporkan serupa. Mereka telah memperbarui resolusi dengan Resolution: Potential fix identified - For a future OS update
. Jari-jari bahwa perbaikan tanah segera.
EDIT: Ini telah diperbaiki di iOS 13.3!
ContentView.swift
. Saya akan mengedit posting, tetapi crash hanya terjadi ketika Anda menavigasi ke depan dan kemudian kembali.Jawaban:
Ini adalah titik yang cukup menyakitkan bagi saya! Saya meninggalkannya sampai sebagian besar aplikasi saya selesai dan saya memiliki ruang pikiran untuk menghadapi tabrakan itu.
Saya pikir kita semua bisa sepakat bahwa ada beberapa hal yang cukup luar biasa dengan SwifUI tetapi proses debugnya sulit.
Menurut pendapat saya, saya akan mengatakan bahwa ini adalah BUG. Inilah alasan saya:
Jika Anda membungkus panggilan pemutusan presentationMode dalam penundaan asinkron sekitar setengah detik, Anda akan menemukan bahwa program tidak akan lagi crash.
Ini menunjukkan kepada saya bahwa bug adalah perilaku yang tidak terduga turun jauh dalam cara SwiftUI berinteraksi dengan semua kode UIKit lainnya untuk mengelola berbagai tampilan. Tergantung pada kode Anda yang sebenarnya, Anda mungkin menemukan bahwa jika ada beberapa kompleksitas kecil dalam tampilan, kerusakan itu sebenarnya tidak akan terjadi. Misalnya, jika Anda menolak dari tampilan ke tampilan yang memiliki daftar, dan daftar itu kosong, Anda akan mendapatkan crash tanpa penundaan asinkron. Di sisi lain, jika Anda hanya memiliki satu entri di tampilan daftar itu, memaksa iterasi loop untuk menghasilkan tampilan induk, Anda akan melihat bahwa crash tidak akan terjadi.
Saya tidak begitu yakin seberapa kuat solusi saya untuk menutup panggilan pemberhentian. Saya harus mengujinya lebih jauh. Jika Anda memiliki ide tentang ini, beri tahu saya! Saya akan sangat senang belajar dari Anda!
sumber
.navigationBarItems()
poin untuk ini menjadi bug.Ini juga membuat saya frustasi selama beberapa waktu. Selama beberapa bulan terakhir, tergantung pada versi Xcode, versi simulator dan jenis perangkat nyata dan / atau versi, itu telah berubah dari bekerja menjadi gagal untuk bekerja lagi, tampaknya secara acak. Namun, baru-baru ini telah gagal secara konsisten untuk saya, jadi kemarin saya mengambil menyelam jauh ke dalamnya. Saat ini saya menggunakan Xcode Versi 11.2.1 (11B500).
Sepertinya masalah berputar di sekitar Nav Bar dan cara tombol ditambahkan ke dalamnya. Jadi alih-alih menggunakan NavigationLink () untuk tombol itu sendiri, saya mencoba menggunakan Tombol standar () dengan aksi yang menetapkan @State var yang mengaktifkan NavigationLink yang tersembunyi. Ini adalah pengganti untuk Robert Parent View:
Bagi saya, ini bekerja sangat konsisten di semua simulator dan semua perangkat nyata.
Inilah pandangan pembantu saya:
Berikut ini contoh penggunaannya:
sumber
Ini adalah bug utama dan saya tidak bisa melihat cara yang tepat untuk mengatasinya. Bekerja dengan baik di iOS 13 / 13.1 tetapi 13.2 macet.
Anda sebenarnya dapat mereplikasi dengan cara yang lebih sederhana (kode ini benar-benar yang Anda butuhkan).
Semoga Apple mengatasinya karena pasti akan memecah banyak aplikasi SwiftUI (termasuk milik saya).
sumber
Sebagai solusinya, berdasarkan jawaban Chuck H di atas, saya telah merangkum NavigationLink sebagai elemen tersembunyi:
Kemudian Anda dapat menggunakannya di dalam NavigationView (yang sangat penting) dan memicunya dari Tombol di bilah navigasi:
Bungkus ini dalam komentar "// HACK" sehingga ketika Apple memperbaikinya, Anda dapat menggantinya.
sumber
Berdasarkan informasi yang kalian berikan dan khususnya komentar yang dibuat oleh @Robert tentang di mana NavigationView ditempatkan, saya telah menemukan cara untuk menyelesaikan masalah setidaknya pada skenario spesifik saya.
Dalam kasus saya, saya memiliki TabView yang terlampir dalam NavigationView seperti ini:
Kode ini macet karena semua orang melaporkan di iOS 13.2 dan berfungsi di iOS 13.1. Setelah beberapa penelitian saya menemukan solusi untuk situasi ini.
Pada dasarnya, saya memindahkan NavigationView ke setiap layar secara terpisah pada setiap tab seperti ini:
Entah bagaimana bertentangan dengan premis kesederhanaan SwiftUI tetapi bekerja di iOS 13.2.
sumber
Xcode 11.2.1 Swift 5
OKE! Butuh beberapa hari untuk memikirkan ini ...
Dalam kasus saya ketika menggunakan SwiftUI saya mendapatkan crash hanya jika bagian bawah daftar saya melampaui layar dan kemudian saya mencoba untuk "memindahkan" item daftar. Apa yang akhirnya saya temukan adalah bahwa jika saya memiliki terlalu banyak "barang" di bawah Daftar () maka crash di pindahkan. Misalnya, di bawah Daftar saya () saya punya Teks (), Spacer (), Tombol (), Spacer () Tombol (). Jika saya berkomentar SATU dari benda-benda itu maka tiba-tiba saya tidak dapat membuat ulang kecelakaan. Saya tidak yakin apa batasannya, tetapi jika Anda mendapatkan crash ini maka cobalah menghapus objek di bawah daftar Anda untuk melihat apakah itu membantu.
sumber
Meskipun saya tidak dapat melihat crash, kode Anda memiliki beberapa masalah:
dengan mengatur item utama, Anda benar-benar membunuh perilaku default transisi navigasi. (coba geser dari sisi depan untuk melihat apakah itu berfungsi).
Jadi tidak perlu ada tombol di sana. Biarkan saja apa adanya dan Anda memiliki tombol kembali yang gratis.
Dan jangan lupa menurut HIG , judul tombol kembali harus menunjukkan ke mana ia pergi, bukan apa itu! Jadi cobalah untuk mengatur judul untuk halaman pertama untuk menunjukkannya salah satu tombol kembali yang muncul untuk itu.
sumber
FWIW - Solusi di atas menyarankan hack NavigationLink yang tersembunyi masih merupakan solusi terbaik di iOS 13.3b3. Saya juga telah mengajukan FB7386339 untuk anak cucu, dan ditutup serupa dengan FB yang disebutkan di atas: "Perbaikan potensial yang diidentifikasi - Untuk pembaruan OS di masa mendatang".
Fingers Crossed.
sumber
Itu diselesaikan di iOS 13.3. Cukup perbarui OS dan xCode Anda.
sumber
.buttonStyle(PlainButtonStyle())
pengubah NavigationLink Anda dan coba lagi. beri tahu saya jika Anda mengajukan pertanyaan.