Ben varsayılan geçersiz kılma NavigationView
ve NavigationLink
istenen davranışı elde sona erdi . Bu kadar basit görünüyor ki varsayılan SwiftUI görünümlerinin yaptığı bir şeye bakmam gerekiyor mu?
NavigationView
SwiftUI içerik görünümünü bir ortamObject olarak veren UINavigationController
süper basit bir sarın . Bu , daha sonra aynı gezinti denetleyicisinde (sunulan görünüm denetleyicileri, ortamObjects almazsa) tam olarak istediğimiz şey olduğu anlamına gelebilir.UIViewControllerRepresentable
UINavigationController
NavigationLink
Not: NavigationView ihtiyacı vardır .edgesIgnoringSafeArea(.top)
ve bunu nasıl yapı kendisi ayarlamak için bilmiyorum. Nvc'niz en üstte kesilirse örneğe bakın.
struct NavigationView<Content: View>: UIViewControllerRepresentable {
var content: () -> Content
init(@ViewBuilder content: @escaping () -> Content) {
self.content = content
}
func makeUIViewController(context: Context) -> UINavigationController {
let nvc = UINavigationController()
let host = UIHostingController(rootView: content().environmentObject(nvc))
nvc.viewControllers = [host]
return nvc
}
func updateUIViewController(_ uiViewController: UINavigationController, context: Context) {}
}
extension UINavigationController: ObservableObject {}
NavigationLink
Bir sonraki görünümü barındıran bir UIHostingController itmek için UINavigationController ortamlarına erişen özel bir NavigationLink oluşturun.
Not: SwiftUI.NavigationLink'in uygulanmadığını selection
ve isActive
henüz ne yaptığını tam olarak anlamadığım için uyguladı. Bu konuda yardım etmek isterseniz lütfen yorum yapın / düzenleyin.
struct NavigationLink<Destination: View, Label:View>: View {
var destination: Destination
var label: () -> Label
public init(destination: Destination, @ViewBuilder label: @escaping () -> Label) {
self.destination = destination
self.label = label
}
/// If this crashes, make sure you wrapped the NavigationLink in a NavigationView
@EnvironmentObject var nvc: UINavigationController
var body: some View {
Button(action: {
let rootView = self.destination.environmentObject(self.nvc)
let hosted = UIHostingController(rootView: rootView)
self.nvc.pushViewController(hosted, animated: true)
}, label: label)
}
}
Bu SwiftUI üzerinde düzgün çalışma geri tokatlamak çözer ve tüm projem hemen bunlara geçti NavigationView ve NavigationLink isimlerini kullandığım için.
Misal
Örnekte ben de modal sunum gösterdim.
struct ContentView: View {
@State var isPresented = false
var body: some View {
NavigationView {
VStack(alignment: .center, spacing: 30) {
NavigationLink(destination: Text("Detail"), label: {
Text("Show detail")
})
Button(action: {
self.isPresented.toggle()
}, label: {
Text("Show modal")
})
}
.navigationBarTitle("SwiftUI")
}
.edgesIgnoringSafeArea(.top)
.sheet(isPresented: $isPresented) {
Modal()
}
}
}
struct Modal: View {
@Environment(\.presentationMode) var presentationMode
var body: some View {
NavigationView {
VStack(alignment: .center, spacing: 30) {
NavigationLink(destination: Text("Detail"), label: {
Text("Show detail")
})
Button(action: {
self.presentationMode.wrappedValue.dismiss()
}, label: {
Text("Dismiss modal")
})
}
.navigationBarTitle("Modal")
}
}
}
Düzenleme: Ben "Bu bir şey göz ardı gerekir o kadar basit görünüyor" ile başladı ve ben buldum düşünüyorum. Bu, EnvironmentObjects'i bir sonraki görünüme aktarmıyor gibi görünüyor. Varsayılan NavigationLink'in bunu nasıl yaptığını bilmiyorum, bu yüzden şimdilik el ile ihtiyacım olan bir sonraki görünüme nesneleri gönderiyorum.
NavigationLink(destination: Text("Detail").environmentObject(objectToSendOnToTheNextView)) {
Text("Show detail")
}
Düzenleme 2:
Bu içindeki tüm görüşlere navigasyon kontrolörü ortaya NavigationView
yaparak @EnvironmentObject var nvc: UINavigationController
. Bunu düzeltmenin yolu, navigasyonu bir dosyaözel sınıfı yönetmek için kullandığımız ortamObject'i yapmaktır. Bunu özde düzelttim: https://gist.github.com/Amzd/67bfd4b8e41ec3f179486e13e9892eeb