আমি ডিফল্টকে ওভাররাইড করে শেষ করে দিয়েছি NavigationViewএবং NavigationLinkপছন্দসই আচরণ পেতে পারি। এটি এত সহজ বলে মনে হচ্ছে যে আমি অবশ্যই ডিফল্ট SwiftUI দর্শনগুলি এমন কিছু উপেক্ষা করব?
NavigationView
আমি UINavigationControllerএকটি সুপার সিম্পলে একটি মোড়ানো করি যা সুইফটইউআই কনটেন্ট ভিউটিকে এনভায়রনমেন্ট অবজেক্ট হিসাবে UIViewControllerRepresentableদেয় UINavigationController। এর অর্থ হ'ল NavigationLinkপরবর্তীতে এটি ধরে নিতে পারে যতক্ষণ না এটি একই নেভিগেশন নিয়ামক হিসাবে থাকে (উপস্থাপিত ভিউ কন্ট্রোলাররা এনভায়রনঅবজেক্টগুলি গ্রহণ করে না) যা আমরা চাই ঠিক তেমনই।
দ্রষ্টব্য: নেভিগেশনভিউয়ের প্রয়োজন .edgesIgnoringSafeArea(.top)এবং স্ট্রাক্টটিতে এটি কীভাবে সেট করা যায় তা আমি জানি না। যদি আপনার এনভিসি শীর্ষে কেটে যায় তবে উদাহরণটি দেখুন।
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
আমি একটি কাস্টম নেভিগেশনলিঙ্ক তৈরি করি যা ইউআইএন হোস্টিংকন্ট্রোলারকে পরবর্তী দৃশ্যের হোস্টিংয়ে ঠেলে পরিবেশগুলি ইউআইএনএভিগেশন কন্ট্রোলার অ্যাক্সেস করে।
দ্রষ্টব্য: আমি বাস্তবায়ন করিনিselectionisActive সুইফটইউআই নেভিগেশনলিঙ্কটি এবং কারণ তারা এখনও কী করে তা আমি পুরোপুরি বুঝতে পারি না। আপনি যদি এটির সাথে সহায়তা করতে চান তবে মন্তব্য / সম্পাদনা করুন।
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)
}
}
এটি পিছনে সোয়াইপগুলি সুইফটুইতে সঠিকভাবে কাজ না করার সমাধান করে এবং কারণ আমি আমার সম্পূর্ণ প্রকল্পটি নেভিগেশনভিউ এবং নেভিগেশনলিঙ্ক নামগুলি ব্যবহার করি ততক্ষনে এইগুলিতে স্যুইচ করা হয়েছে।
উদাহরণ
উদাহরণে আমি মোডাল উপস্থাপনাটিও দেখাই।
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")
}
}
}
সম্পাদনা: আমি "এটি এত সহজ বলে মনে হচ্ছে যে আমি অবশ্যই কিছু উপেক্ষা করব" এবং আমি মনে করি এটি খুঁজে পেয়েছি। এটি পরিবেশের বিষয়গুলি পরের দৃশ্যে স্থানান্তরিত করে বলে মনে হচ্ছে না। আমি জানি না যে ডিফল্ট নেভিগেশনলিঙ্ক কীভাবে এটি করে তাই আপাতত আমি নিজেই যেখানে প্রয়োজন সেখানে পরবর্তী দর্শনে ম্যানুয়ালি প্রেরণ করি।
NavigationLink(destination: Text("Detail").environmentObject(objectToSendOnToTheNextView)) {
Text("Show detail")
}
সম্পাদনা 2:
এটি করে নেভিগেশন কন্ট্রোলারটিকে অভ্যন্তরীণ সমস্ত দর্শনে প্রকাশিত NavigationViewকরে @EnvironmentObject var nvc: UINavigationController। এটি ঠিক করার উপায়টি পরিবেশ ফাইলকে তৈরি করা হচ্ছে যা আমরা ফাইলপ্রাইভেট শ্রেণীর নেভিগেশন পরিচালনা করতে ব্যবহার করি। আমি এটিকে সংক্ষেপে ঠিক করেছি: https://gist.github.com/Amzd/67bfd4b8e41ec3f179486e13e9892eeb