Update: This was a red herring
So my original question asked how to make a navigation link disabled and only enabled if two Toggle
affecting two @State var isXYZToggleOn Bool
properties are both true. This has always been working, my first attempt using .disabled(!(hasAgreedToTermsAndConditions && hasAgreedToPrivacyPolicy))
was the correct one (also suggested by @superpuccio, but using two negatations and one boolean or (||
)).
Turns I did not get my NavigationLink
to be enabled because the toggling did not work, not because of incorrect usage of the booleans and disabled
view modifier.
Running on device, instead of simulator made everything work! But I still see the warning message as soon as I press any Toggle
(but only once):
invalid mode 'kCFRunLoopCommonModes' provided to CFRunLoopRunSpecific - break on _CFRunLoopError_RunCalledWithInvalidMode to debug. This message will only appear once per execution.
I get this error message running on simulator too, but then the NavigationLink
does not get enabled ever.
I'm running Xcode 5 beta on Catalina 5 beta on a 2016 Macbook Pro. Deleting derived data, restarting Xcode, restarting my computer, resetting the simulator, changing simulator, nothing helps. I still see invalid mode 'kCFRunLoopCommonModes'
when I press the first Toggle
, and the NavigationLink
never gets enabled.
So the new question is:
Running on simulator: how to solve invalid mode 'kCFRunLoopCommonModes'
problem causing my @State
bound to Toggle
to never become true
??
Original question
Using XCode 11 beta 5 and SwiftUI. In a WelcomeScene
I have two Toggle
views, one toggle for accepting Terms & Conditions and one toggle for Privacy Policy. These toggles updates two separate @State
properties respectively.
In the bottom of the scene I have a NagivationLink
(button) which will take to the next scene, which I would like to be disabled by default and only be enabled when both hasAgreedToTermsAndConditions
and hasAgreedToPrivacyPolicy
states are true
.
When initiating a NavigationLink
there is a isActive
argument, which takes a Binding<Bool>
, which sounds like the correct thing. However, @Binding
properties cannot be marked lazy
, thus I cannot make it a computed property being dependent on hasAgreedToTermsAndConditions
and hasAgreedToPrivacyPolicy
.
There is also a disabled
view modifier which takes a Bool
, which is also incorrect since it does not get updated...
struct WelcomeScene: View {
@State var hasAgreedToTermsAndConditions: Bool = false
@State var hasAgreedToPrivacyPolicy: Bool = false
var body: some View {
VStack {
Image(named: "MyImage")
Spacer()
Text("Welcome friend!".uppercased())
.font(.system(size: 55))
Toggle(isOn: $hasAgreedToTermsAndConditions) {
Text("I agree to the Terms and Conditions")
}.toggleStyle(DefaultToggleStyle())
Toggle(isOn: $hasAgreedToPrivacyPolicy) {
Text("I agree to the Privacy Policy")
}.toggleStyle(DefaultToggleStyle())
// This does not compile 'Binding<Bool> is not convertible to Bool', but I cannot figure out how to create a compupted property binding using those 2 states...
NavigationLink("Proceed", destination: SignInScene(), isActive: ($hasAgreedToTermsAndConditions && $hasAgreedToPrivacyPolicy))
}.padding(30)
}
}
How can I make a NavigationLink
disabled
by default and only enabled
when both toggles are on
?