I'm implementing a very custom NavigationLink called MenuItem
and would like to reuse it across the project. It's a struct that conforms to View
and implements var body : some View
which contains a NavigationLink
.
I need to somehow store the view that shall be presented by NavigationLink
in the body of MenuItem
but have yet failed to do so.
I have defined destinationView
in MenuItem
's body as some View
and tried two initializers:
This seemed too easy:
struct MenuItem: View {
private var destinationView: some View
init(destinationView: View) {
self.destinationView = destinationView
}
var body : some View {
// Here I'm passing destinationView to NavigationLink...
}
}
--> Error: Protocol 'View' can only be used as a generic constraint because it has Self or associated type requirements.
2nd try:
struct MenuItem: View {
private var destinationView: some View
init<V>(destinationView: V) where V: View {
self.destinationView = destinationView
}
var body : some View {
// Here I'm passing destinationView to NavigationLink...
}
}
--> Error: Cannot assign value of type 'V' to type 'some View'.
Final try:
struct MenuItem: View {
private var destinationView: some View
init<V>(destinationView: V) where V: View {
self.destinationView = destinationView as View
}
var body : some View {
// Here I'm passing destinationView to NavigationLink...
}
}
--> Error: Cannot assign value of type 'View' to type 'some View'.
I hope someone can help me. There must be a way if NavigationLink can accept some View as an argument. Thanks ;D
You can create your custom view like this:
Using:
You can pass a NavigationLink (or any other view widget) as a variable to a subview as follows:
I really struggled to make mine work for an extension of
View
. Full details about how to call it are seen here.The extension for
View
(using generics) - remember toimport SwiftUI
:You should make the generic parameter part of
MenuItem
:The way Apple does it is using function builders, there is a predefined one called ViewBuilder, make the last argument, or only argument, of you init method for MenuItem this
assign it to a property defined something like
and then where you want to output the Views just call the function like
then you can do
This will let you pass up to 10 view and use if conditions etc. though if you want it to be more restrictive you will have to define your own function builder. I haven't done that so you will have to google that.