-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Fix] Custom Boolean bindings bug on Mac Catalyst #358
[Fix] Custom Boolean bindings bug on Mac Catalyst #358
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Few suggestions
Shared/Samples/Find route around barriers/FindRouteAroundBarriersView.Views.swift
Outdated
Show resolved
Hide resolved
_routingFindsBestSequence = State(initialValue: routeParameters.findsBestSequence) | ||
_routePreservesFirstStop = State(initialValue: routeParameters.preservesFirstStop) | ||
_routePreservesLastStop = State(initialValue: routeParameters.preservesLastStop) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any specific reason to use State(initialValue:)
?
_routingFindsBestSequence = State(initialValue: routeParameters.findsBestSequence) | |
_routePreservesFirstStop = State(initialValue: routeParameters.preservesFirstStop) | |
_routePreservesLastStop = State(initialValue: routeParameters.preservesLastStop) | |
self.routingFindsBestSequence = routeParameters.findsBestSequence | |
self.routePreservesFirstStop = routeParameters.preservesFirstStop | |
self.routePreservesLastStop = routeParameters.preservesLastStop | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The doc is pretty clear that state properties should not be set in an initializer, neither by explicitly calling init(initialValue:)
nor by implicitly calling init(wrappedValue:)
:
You don’t call this initializer directly. Instead, SwiftUI calls it for you when you declare a property with the @State attribute and provide an initial value
The reason being is that state is a private, implementation detail. The parent view's body being re-computed shouldn't alter the view's state, which is what happens when a state property is set from inside an initializer. For values provided by an initializer, non-state properties should be used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@philium sorry I missed your comment. Would it be better to use bindings here in this case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I took a closer look at what this sample is doing and in this case, I don't see an alternative option that isn't more complicated. As I mentioned, the concern with setting the state in an initializer is that the state will be reset every time the parent's body is re-computed, but in this case, that isn't an issue. (In an ideal world, RouteParameters
would be a struct and the settings view would take a binding to it. Then everything would just work without needing separate state properties.)
A couple other things I noticed:
- The settings view initializer parameter label should be
routeParameters
instead offor
. From the Swift API Design Guidelines: "The first argument to initializer…calls should not form a phrase starting with the base name, e.g. x.makeWidget(cogCount: 47)" - The settings view should use
Form
instead ofList
, asForm
is "a container for grouping controls used for data entry, such as in settings or inspectors."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@philium Sounds good. I'll make another PR to address those issues.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The settings view should use Form instead of List
here is a card for SprintX 😼
Shared/Samples/Group layers together/GroupLayersTogetherView.GroupLayerListView.swift
Show resolved
Hide resolved
Shared/Samples/Group layers together/GroupLayersTogetherView.GroupLayerListView.swift
Outdated
Show resolved
Hide resolved
Co-authored-by: Nimesh Jarecha <njarecha@esri.com>
Shared/Samples/Group layers together/GroupLayersTogetherView.GroupLayerListView.swift
Outdated
Show resolved
Hide resolved
Thank you guys for reviewing! |
Description
This PR implements a fix for a bug where toggle states would not update on Mac Catalyst when a custom binding was used. The bindings were replaced with State variables that trigger updates to a given value through an
onChange
modifier.Sample affected:
Linked Issue(s)
swift/issues/4994
How To Test