I'm trying to navigate and/or present fullscreen using the NavigationLink and it will vary based on the condition. When I'm trying to do that, I'm getting the compilation error as Type '() -> ()' cannot conform to 'View'
. Is there any way I can achieve this?
Note: I tried to hide the NavigationBar
for my ErrorView
. so that I can able to just see the content. Since I'm doing this from HostingViewController, I can able to see the HostingViewController
navigation bar for my ErrorView
as well. That's the reason why I trying the .fullScreenCover
approach.
import SwiftUI
struct LoginView: View {
@State private var isSelected: Bool = false
@State private var isSuccess: Bool = false
var nextButton: some View {
HStack {
NavigationLink("Test") {
if isSuccess {
HomeView(user: user)
} else {
isSelected.toggle()
}
}
.fullScreenCover(isPresented: $isSelected) {
ErrorView()
}
.buttonStyle(PlainButtonStyle())
.font(.system(size: 24))
}
}
var body: some View {
NavigationStack {
nextButton
}
}
}
CodePudding user response:
This will rid the error message.
struct LoginView: View {
@State var isSuccess: Bool = false
var body: some View {
NavigationStack {
NavigationLink {
HomeView()
} label: {
Text("Login")
}
.fullScreenCover(isPresented: .constant(!isSuccess), content: {
ErrorView()
})
.buttonStyle(PlainButtonStyle())
.font(.system(size: 24))
}
}
}
CodePudding user response:
The problem is that isSelected.toggle()
is not a view and thus cannot be used in the destination argument. You shouldn't try to execute code that mutates variables in view building functions.
Also, when you click on a NavigationLink, its destination will be presented. Since the old isActive
NavigationLink is deprecated, I don't think you can prevent the presentation of the destination. Maybe by pushing a nil value but I haven't tried that.
So my proposed solution uses a button instead of a NavigationLink. If isSuccess
it can navigate to your desired view else it pops up the error full screen cover.
But using a path in a NavigationStack can get pretty complicated imo.
struct LoginView: View {
struct UserInfo: Hashable {
var name: String
var email: String
}
enum Path: Hashable {
case user(UserInfo)
}
@State private var isSelected: Bool = false
@State private var isSuccess: Bool = true
@State var path: [Path] = []
var nextButton: some View {
HStack {
Button {
if isSuccess {
path.append(Path.user(UserInfo(name: "Subbu", email: "")))
} else {
isSelected = true
}
} label: {
Text("Test")
}
.buttonStyle(.plain)
.font(.system(size: 24))
}
.fullScreenCover(isPresented: $isSelected) {
Text("ErrorView")
}
}
var body: some View {
NavigationStack(path: $path) {
nextButton
.navigationDestination(for: Path.self) { pathItem in
switch(pathItem) {
case .user(let userInfo):
Text("\(userInfo.name)")
}
}
}
}
}