I've created a UserDefaults extension to generate custom bindings.
extension UserDefaults {
func boolBinding(for defaultsKey: String) -> Binding<Bool> {
return Binding (
get: { return self.bool(forKey: defaultsKey) },
set: { newValue in
self.setValue(newValue, forKey: defaultsKey)
})
}
func cardPileBinding(for defaultsKey: String) -> Binding<CardPile> {
return Binding (
get: { let rawValue = self.object(forKey: defaultsKey) as? String ?? ""
return CardPile(rawValue: rawValue) ?? .allRandom
},
set: { newValue in
self.setValue(newValue.rawValue, forKey: defaultsKey)
})
}
}
For the sake of completeness, here is my enum
enum CardPile: String, CaseIterable {
case allRandom
case numbers
case numbersRandom
case daysMonths
case daysMonthsRandom
}
I've also created UI elements that use these bindings:
var body: some View {
VStack {
Toggle("Enable", isOn: UserDefaults.standard.boolBinding(for: "enable"))
Picker("Card Pile", selection: UserDefaults.standard.cardPileBinding(for: "cardPile")) {
ForEach(CardPile.allCases,
id: \.self) {
Text("\($0.rawValue)")
.tag($0.rawValue)
}
}
}
}
When I tap the toggle, it updates correctly. However when I tap the picker and select a different value, the binding setter gets called, but the view does not refreshed to reflect the change in value. (If I force quit the app and re-run it, the I see the change.)
I would like to find out why the Binding works as I'd expected (ie updates the UI when the value changes) but the Binding behaves differently.
any/all guidance very much appreciated.
Note: I get the same behavior when the enum use Int as its rawValue
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
I have a view containing either a TextField or a SecureField. I'm hoping I can use a single FocusState value that will apply to either the TextField or SecureField. (I'm using FocusState to ensure the cursor will be in the field when it initially loads)
I've verified this works in a sample project when the view is in a WindowGroup. But when I instead use a DocumentGroup ~50% of the time when the view loads/launches, it does not have focus.
Here is my ContentView:
struct ContentView: View {
let coinFlip: Bool = .random() // used to choose between the TextField and the SecureField
@State var fieldContent: String = "" // bound to the Field value
@FocusState var focus: Bool
var body: some View {
VStack {
Text("Coin Flip: \(coinFlip)")
actualField
.focused($focus, equals: true)
}
.onAppear() {
focus = true
}
}
@ViewBuilder var actualField: some View {
if coinFlip {
TextField("Enter text here", text: $fieldContent)
} else {
SecureField("Enter secure text here", text: $fieldContent)
}
}
}
and here is my App swift file
@main
struct ModernTurtleApp: App {
var body: some Scene {
// WindowGroup {
// ContentView()
// }
DocumentGroup(newDocument: ModernTurtleDocument()) { file in
ContentView()
}
}
}
When this code runs, the Field has focus about 50% of the time on initial launch. When I uncomment the WindowGroup and comment the DocumentGroup, the field always has focus on initial launch.
I realize I can work around this behaviour by using an optional enum for FocusState. I would be ok going this route, but I first want to try to understand the behaviour I'm seeing, and possibly keep my simpler FocusState implementation.
Thanks, in advance for any help.
In Xcode Version 16.1
Create a new Project, choose Multiplatform, App
For testing system, choose XCTest and UI Tests
In the project, open the newly generated template Unit test file
Click either of the diamonds in the left margin (either to run the example test or the entire file)
Expected Result: Code compiles and then Runs the test/tests
Actual Result: Code compiles, but then never completes testing (the top status bar is stuck saying "Testing..." forever.)
Am I missing something?
The app I'm converting includes two unique document types. UI-wise they have key similarities (eg contents are password protected) But serialization/model - wise. they are different documents. I have not been able to find any documentation on options for implementing this (eg use a (abstract?) base class derived from FileDocument, with two concrete sub classes? maybe just a single subclass of FileDocument that contains model details for both file types?)
Stepping back from implementation options, am I crazy for attempting to use DocumentGroup to create a single app that would need to be able to open/modify/save multiple unique document types?
any/all guidance much appreciated.
Topic:
UI Frameworks
SubTopic:
SwiftUI
As the title suggests, I have a class marked with @Observable. Within the class I have multiple var's. When one of my var's changes (formation), I want to run an updateOrCreateContent(). I had thought I could just do this with a bit of combine, but I'm struggling to get it working...
The code below has a compile error at $formation
When I mark formation @Published, it generates a different compile error: "Invalid redeclaration of synthesized property '_formation'"
any help appreciated
thanks
class LayoutModel {
var players: [Player] = []
var formation: Formation = .f433
var cancellables = Set<AnyCancellable>()
init(players: [Player], formation: Formation) {
self.players = players
self.formation = formation
updateOrCreateContent()
$formation.sink(receiveValue: { _ in
self.updateOrCreateContent()
})
.store(in: &cancellables)
}