Skip to content

Commit d8ef148

Browse files
stephencelismluisbrown
authored andcommitted
Add more workarounds for disabled field SwiftUI bug (#1147)
1 parent 43432e0 commit d8ef148

File tree

4 files changed

+32
-1
lines changed

4 files changed

+32
-1
lines changed

Examples/CaseStudies/CaseStudies.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
DC5B505125C86EBC000D8DFD /* 01-GettingStarted-Bindings-Forms.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC5B505025C86EBC000D8DFD /* 01-GettingStarted-Bindings-Forms.swift */; };
6262
DC630FDA2451016B00BAECBA /* ListsOfState.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC630FD92451016B00BAECBA /* ListsOfState.swift */; };
6363
DC634B252448D15B00DAA016 /* 04-HigherOrderReducers-ReusableFavoritingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC634B242448D15B00DAA016 /* 04-HigherOrderReducers-ReusableFavoritingTests.swift */; };
64+
DC85EBC3285A731E00431CF3 /* ResignFirstResponder.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC85EBC2285A731E00431CF3 /* ResignFirstResponder.swift */; };
6465
DC88D8A6245341EC0077F427 /* 01-GettingStarted-Animations.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC88D8A5245341EC0077F427 /* 01-GettingStarted-Animations.swift */; };
6566
DC89C41B24460F95006900B9 /* 00-RootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC89C41A24460F95006900B9 /* 00-RootView.swift */; };
6667
DC89C41D24460F96006900B9 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DC89C41C24460F96006900B9 /* Assets.xcassets */; };
@@ -207,6 +208,7 @@
207208
DC5B505025C86EBC000D8DFD /* 01-GettingStarted-Bindings-Forms.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "01-GettingStarted-Bindings-Forms.swift"; sourceTree = "<group>"; };
208209
DC630FD92451016B00BAECBA /* ListsOfState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListsOfState.swift; sourceTree = "<group>"; };
209210
DC634B242448D15B00DAA016 /* 04-HigherOrderReducers-ReusableFavoritingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "04-HigherOrderReducers-ReusableFavoritingTests.swift"; sourceTree = "<group>"; };
211+
DC85EBC2285A731E00431CF3 /* ResignFirstResponder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResignFirstResponder.swift; sourceTree = "<group>"; };
210212
DC88D8A5245341EC0077F427 /* 01-GettingStarted-Animations.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "01-GettingStarted-Animations.swift"; sourceTree = "<group>"; };
211213
DC89C41324460F95006900B9 /* SwiftUICaseStudies.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SwiftUICaseStudies.app; sourceTree = BUILT_PRODUCTS_DIR; };
212214
DC89C41A24460F95006900B9 /* 00-RootView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "00-RootView.swift"; sourceTree = "<group>"; };
@@ -450,6 +452,7 @@
450452
isa = PBXGroup;
451453
children = (
452454
CA6AC2612451135C00C71CB3 /* CircularProgressView.swift */,
455+
DC85EBC2285A731E00431CF3 /* ResignFirstResponder.swift */,
453456
DCC68EDE2447BC810037F998 /* TemplateText.swift */,
454457
DC9EB4162450CBD2005F413B /* UIViewRepresented.swift */,
455458
);
@@ -758,6 +761,7 @@
758761
DC89C41B24460F95006900B9 /* 00-RootView.swift in Sources */,
759762
DCC68EDD2447A5B00037F998 /* 01-GettingStarted-OptionalState.swift in Sources */,
760763
CABC4F3926AEE00C00D5FA2C /* 02-Effects-Refreshable.swift in Sources */,
764+
DC85EBC3285A731E00431CF3 /* ResignFirstResponder.swift in Sources */,
761765
DCC68EAB244666AF0037F998 /* 03-Navigation-Sheet-PresentAndLoad.swift in Sources */,
762766
CAE962FD24A7F7BE00EFC025 /* 01-GettingStarted-AlertsAndConfirmationDialogs.swift in Sources */,
763767
CA25E5D224463AD700DA666A /* 01-GettingStarted-Bindings-Basics.swift in Sources */,

Examples/CaseStudies/SwiftUICaseStudies/01-GettingStarted-Bindings-Basics.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ struct BindingBasicsView: View {
7979

8080
Toggle(
8181
isOn: viewStore.binding(get: \.toggleIsOn, send: BindingBasicsAction.toggleChanged)
82+
.resignFirstResponder()
8283
) {
8384
Text("Disable other controls")
8485
}

Examples/CaseStudies/SwiftUICaseStudies/01-GettingStarted-Bindings-Forms.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,11 @@
6464
}
6565
.disabled(viewStore.toggleIsOn)
6666

67-
Toggle("Disable other controls", isOn: viewStore.binding(\.$toggleIsOn))
67+
Toggle(
68+
"Disable other controls",
69+
isOn: viewStore.binding(\.$toggleIsOn)
70+
.resignFirstResponder()
71+
)
6872

6973
Stepper(value: viewStore.binding(\.$stepCount), in: 0...100) {
7074
Text("Max slider value: \(viewStore.stepCount)")
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#if canImport(SwiftUI)
2+
import SwiftUI
3+
4+
extension Binding {
5+
/// SwiftUI will print errors to the console about "AttributeGraph: cycle detected" if you disable
6+
/// a text field while it is focused. This hack will force all fields to unfocus before we write
7+
/// to a binding that may disable the fields.
8+
///
9+
/// See also: https://stackoverflow.com/a/69653555
10+
func resignFirstResponder() -> Self {
11+
Self(
12+
get: { self.wrappedValue },
13+
set: { newValue, transaction in
14+
UIApplication.shared.sendAction(
15+
#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil
16+
)
17+
self.transaction(transaction).wrappedValue = newValue
18+
}
19+
)
20+
}
21+
}
22+
#endif

0 commit comments

Comments
 (0)