Reputation: 65
In swiftui how do i only make a navigation link active after a selection is made? I've included a screenshot. I'd like to be able to select either one option or multiple, but don't want the next button to be highlighted until at least one option is chosen.
import SwiftUI
struct AudienceView: View {
@State var isOn_w = false
@State var isOn_m = false
@State var isOn_g = false
@State var isOn_b = false
var body: some View {
VStack {
Text("Audience")
.fontWeight(/*@START_MENU_TOKEN@*/.bold/*@END_MENU_TOKEN@*/)
.font(.title2)
.frame(
minWidth: 0,
maxWidth: .infinity,
alignment: .center
)
Spacer()
ScrollView{
Toggle(isOn: $isOn_w)
{Text("Women")
.WithDefaultButtonTextFormatting()
}
.WithDefaultToggleSelectedFormatting()
Toggle(isOn: $isOn_m)
{Text("Men")
.WithDefaultButtonTextFormatting()
}
.WithDefaultToggleSelectedFormatting()
Toggle(isOn: $isOn_g)
{Text("Girls")
.WithDefaultButtonTextFormatting()
}
.WithDefaultToggleSelectedFormatting()
Toggle(isOn: $isOn_b)
{Text("Boys")
.WithDefaultButtonTextFormatting()
}
.WithDefaultToggleSelectedFormatting()
}
NavigationLink(destination: AgeCategoryView(), label: {Text("Next")})
.padding(.bottom)
}
}
}
Upvotes: 0
Views: 410
Reputation: 36304
you could try this approach using an ObservableObject
:
struct ContentView: View {
var body: some View {
NavigationView {
AudienceView()
}
}
}
class AudienceViewModel: ObservableObject {
@Published var isOn_w = false {
didSet { isActive = isOn_w || isOn_m || isOn_g || isOn_b }
}
@Published var isOn_m = false {
didSet { isActive = isOn_w || isOn_m || isOn_g || isOn_b }
}
@Published var isOn_g = false {
didSet { isActive = isOn_w || isOn_m || isOn_g || isOn_b }
}
@Published var isOn_b = false {
didSet { isActive = isOn_w || isOn_m || isOn_g || isOn_b }
}
@Published var isActive = false
}
struct AudienceView: View {
@StateObject var model = AudienceViewModel()
var body: some View {
VStack {
Text("Audience")
.fontWeight(.bold)
.font(.title2)
.frame(
minWidth: 0,
maxWidth: .infinity,
alignment: .center
)
Spacer()
ScrollView {
Toggle(isOn: $model.isOn_w)
{Text("Women")
.WithDefaultButtonTextFormatting()
}
.WithDefaultToggleSelectedFormatting()
Toggle(isOn: $model.isOn_m)
{Text("Men")
.WithDefaultButtonTextFormatting()
}
.WithDefaultToggleSelectedFormatting()
Toggle(isOn: $model.isOn_g)
{Text("Girls")
.WithDefaultButtonTextFormatting()
}
.WithDefaultToggleSelectedFormatting()
Toggle(isOn: $model.isOn_b)
{Text("Boys")
.WithDefaultButtonTextFormatting()
}
.WithDefaultToggleSelectedFormatting()
}
if model.isActive {
NavigationLink("Next", destination: AgeCategoryView()).padding(.bottom)
} else {
Text("Next").foregroundColor(.gray).padding(.bottom)
}
}
}
}
You could also do the "short cut" using your vars, like this:
if isOn_w || isOn_m || isOn_g || isOn_b {
NavigationLink("Next", destination: AgeCategoryView()).padding(.bottom)
} else {
Text("Next").foregroundColor(.gray).padding(.bottom)
}
Upvotes: 1
Reputation: 313
You can add an .opacity()
modifier to you Navigation Link to show it only when condition is met. You can provide logic for selection like this:
var selectionMade: Bool {
if isOn_w == true || isOn_m == true || isOn_g == true || isOn_b == true {
return true
} else {
return false
}
}
And than attach it to you Navigation Link
:
NavigationLink(destination: AgeCategoryView(), label: {Text("Next")})
.padding(.bottom)
.opacity(selectionMade ? 1 : 0)
Upvotes: 0