Post

Replies

Boosts

Views

Activity

Reply to Unable to change Toggles
Move the @State property wrapper from the selected variable in the mySession struct to the sessions array. You can then pass a binding directly into the Toggle, like this: ForEach($sessions) { $session in Toggle(isOn: $session.selected) { Text(session.name) } }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Jul ’22
Reply to NavigationSplitView with Custom Views as Labels
I'm not really sure what you're asking. If you want to know how to show a different view based on the current selection then you can see the ammended code below: @State var selectedNavigationCategory: NavigationCategory? let navigationCategories = [     NavigationCategory(id: UUID(), name: "One", sfSymbol: "circle"),     NavigationCategory(id: UUID(), name: "Two", sfSymbol: "circle.fill") ] var body: some View {     NavigationSplitView {         List(navigationCategories, selection: $selectedNavigationCategory) { category in             NavigationLink(value: category) {                 Label(category.name, systemImage: category.sfSymbol)             }         }     } detail: {         ZStack { // workaround in beta 2             if let selectedNavigationCategory {                 // Something has been selected // Show the corresponding view for this                 Text("You selected \(selectedNavigationCategory.name)")             } else {                 // Nothing is selected // Placeholder text                 Text("Select something")             }         }     } }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Jun ’22
Reply to MyEqualWidthHStack WWDC example not working for me
A lot of people have been experiencing different behaviours with the new Layout API and they each have different solutions. Resolved in iOS & iPadOS 16 beta 2, passing multiple children to a custom Layout now compiles. This means that a Group or another container is no longer required. The other issue arises from how the layout views are created under the hood. Two solutions for this are either wrapping the layout name in parentheses: (CustomLayout()) { Text("Hello, World") Text("Hello, World") } or creating an initialiser for the custom Layout that accepts no parameters: init() {} ... CustomLayout { Text("Hello, World") Text("Hello, World") }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Jun ’22
Reply to NavigationStack Being Automatically dismissed
One thing that may be causing this is that fact that the FruitDetailView contains a NavigationStack, when it's parent, ContentView, already wraps it in one. If removing the inner NavigationStack doesn't work, then maybe it's a bug. I'm not sure how related this is but from the release notes: A view-based NavigationLink in a List fails to update the visible selection of the list. (92193873)
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Jun ’22
Reply to SwiftUI Textfield Alert for macOS
macOS 13 Beta Release Notes SwiftUI New Features • You can now place a TextField in an Alert by using alert modifiers that accept a ViewBuilder . (64819930) I haven't tested it yet as I'm still using Monterey, but it should work according to the release notes. If you are looking for macOS 12 and earlier solutions, you can do something like this: Button("Tap Me") { let alert = NSAlert() alert.messageText = "Alert with text field"     alert.addButton(withTitle: "OK") // You can customise this text field, this is just an example.     alert.accessoryView = NSTextField(string: "Text")                  alert.runModal() }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Jun ’22
Reply to EditView Reference is Broken
The problem is that you have attached the .sheet modifier to the view inside of the ForEach, which means that every view has that sheet that presents its own version of EditView. Also the .contextMenu modifier should be attached to each view in the ForEach so it has access to the object that has been selected. I have changed your code so that this should (theoretically) work. // When the button in the context menu is tapped, the index of the corresponding object is stored in the selectedObjectIndex variable. // This triggers the sheet to appear with an unwrapped selectedObjectIndex which is used to get the object that is passed to the EditView. struct ContentView: View { @State private var objectList = [Object(title: "First", string: "Editor"), Object(title: "Second", string: "Addition"), Object(title: "Third", string: "Twelve")]     @State private var selectedObjectIndex: Int?         var body: some View {         NavigationView{             List{                 Section("Objects"){                     ForEach(objectList) { object in                         NavigationLink(destination: ObjectView(obj: object)){                             Text(object.title)                         } .contextMenu{ // move inside ForEach                     Button(action: {                         self.selectedObjectIndex = objectList.firstIndex(of: object)                     }){                         Text("Edit Item")                     }                 }                     }                 } .sheet(item: $selectedObjectIndex) { index in // move outside ForEach and use item initialiser                 EditView(obj: objectList[index])                 }             }             .listStyle(InsetGroupedListStyle())             .cornerRadius(10)             .navigationBarTitle("My List")         }     } }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Jun ’22
Reply to SwiftUI & Layout API. Extra trailing closure passed in call
The method behind the trailing closure accepts a closure as a parameter that can only return a single view. func callAsFunction<V>(_ content: () -> V) -> some View where V : View Since its not marked with @ViewBuilder, like most of the other SwiftUI view closures, you can only return one view. So your view will have to be declared like this if you want multiple views: MyStairsStack() { Group { Text("Hello, World!") Text("Hello, World!") Text("Hello, World!") } }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Jun ’22
Reply to placeholderText Color
If you want the placeholderText property for SwiftUI's Color, you can access it like this: Color(uiColor: .placeholderText) You can also wrap this inside of an extension on Color for simpler code.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Jun ’22
Reply to Canceling an Edit: When to alert?
Here's my attempt at using the hasChanges property. It sort of combines the two approaches. See what you think – I'm not sure how well it works though. There is an entity called Item with three attributes: name: String, detail: String, amount: Int16 (for reproducibility). I used the template PersistenceController struct to inject the managedObjectContext into the views. struct ContentView: View {     @Environment(\.managedObjectContext) private var viewContext     @FetchRequest(sortDescriptors: []) private var items: FetchedResults<Item>     @State private var selectedItem: Item?     var body: some View {         NavigationStack {             List(items) { item in                 Button {                     selectedItem = item                 } label: {                     LabeledContent(item.title ?? "No name", value: item.amount, format: .number)                 }             }             .sheet(item: $selectedItem, content: EditView.init)             .toolbar {                 Button(action: addItem) {                     Label("Add Item", systemImage: "plus")                 }             }         }     }     private func addItem() {         withAnimation {             let newItem = Item(context: viewContext)             newItem.title = "New Item"             do {                 try viewContext.save()             } catch {                 fatalError("Failed to save: \(error.localizedDescription)")             }         }     } } struct EditView: View {     @Environment(\.dismiss) private var dismiss     @State private var showingCancelAlert = false     @State private var title: String     @State private var detail: String     @State private var amount: Int     let item: Item     init(item: Item) {         self.item = item         _title = State(wrappedValue: item.title ?? "")         _detail = State(wrappedValue: item.detail ?? "")         _amount = State(wrappedValue: Int(item.amount))     }     var body: some View {         NavigationStack {             Form {                 Section {                     TextField("Title", text: $title)                         .onSubmit {                             item.title = title                         }                     TextField("Description", text: $detail)                         .onSubmit {                             item.detail = detail                         }                 }                 Stepper("Amount: \(amount)", value: $amount) { _ in                     item.amount = Int16(amount)                 }             }             .navigationTitle("Edit Item")             .navigationBarTitleDisplayMode(.inline)             .toolbar {                 ToolbarItem(placement: .cancellationAction) {                     Button("Cancel", role: .cancel) {                         if item.hasChanges {                             showingCancelAlert = true                         } else {                             dismiss()                         }                     }                     .confirmationDialog("You have unsaved changes", isPresented: $showingCancelAlert) {                         Button("Discard Changes", role: .destructive, action: dismiss.callAsFunction)                     }                 }                 ToolbarItem(placement: .confirmationAction) {                     Button("Done", action: dismiss.callAsFunction)                         .disabled(!item.hasChanges)                 }             }         }         .interactiveDismissDisabled()     } }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Jun ’22
Reply to Canceling an Edit: When to alert?
I believe NSManagedObject has a hasChanges property so you can check that boolean value, however this requires you to update the object directly whenever the user changes something. The other option would be doing what @Claude31 suggested, or manually checking each property for a change between the current stored value and the one the user is modifying.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Jun ’22
Reply to Unable to change Toggles
Move the @State property wrapper from the selected variable in the mySession struct to the sessions array. You can then pass a binding directly into the Toggle, like this: ForEach($sessions) { $session in Toggle(isOn: $session.selected) { Text(session.name) } }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Jul ’22
Reply to Hi swiftUI guys, how can I use variable color? can't find how
Just use the new initialiser for Image like this: Image(systemName: "wifi", variableValue: 0.5)
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Jun ’22
Reply to NavigationSplitView with Custom Views as Labels
I'm not really sure what you're asking. If you want to know how to show a different view based on the current selection then you can see the ammended code below: @State var selectedNavigationCategory: NavigationCategory? let navigationCategories = [     NavigationCategory(id: UUID(), name: "One", sfSymbol: "circle"),     NavigationCategory(id: UUID(), name: "Two", sfSymbol: "circle.fill") ] var body: some View {     NavigationSplitView {         List(navigationCategories, selection: $selectedNavigationCategory) { category in             NavigationLink(value: category) {                 Label(category.name, systemImage: category.sfSymbol)             }         }     } detail: {         ZStack { // workaround in beta 2             if let selectedNavigationCategory {                 // Something has been selected // Show the corresponding view for this                 Text("You selected \(selectedNavigationCategory.name)")             } else {                 // Nothing is selected // Placeholder text                 Text("Select something")             }         }     } }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Jun ’22
Reply to MyEqualWidthHStack WWDC example not working for me
A lot of people have been experiencing different behaviours with the new Layout API and they each have different solutions. Resolved in iOS & iPadOS 16 beta 2, passing multiple children to a custom Layout now compiles. This means that a Group or another container is no longer required. The other issue arises from how the layout views are created under the hood. Two solutions for this are either wrapping the layout name in parentheses: (CustomLayout()) { Text("Hello, World") Text("Hello, World") } or creating an initialiser for the custom Layout that accepts no parameters: init() {} ... CustomLayout { Text("Hello, World") Text("Hello, World") }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Jun ’22
Reply to Disabling Drag Gesture on Button in paged TabView
Trying adding this to the buttons: .highPriorityGesture(DragGesture())
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Jun ’22
Reply to NavigationStack Being Automatically dismissed
One thing that may be causing this is that fact that the FruitDetailView contains a NavigationStack, when it's parent, ContentView, already wraps it in one. If removing the inner NavigationStack doesn't work, then maybe it's a bug. I'm not sure how related this is but from the release notes: A view-based NavigationLink in a List fails to update the visible selection of the list. (92193873)
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Jun ’22
Reply to NavigationSplitView sidebar Links not working after navigating back
iOS & iPadOS 16 Beta Release Notes SwiftUI Known Issues • Selection-driven, three-column NavigationSplitView sometimes fails to push when collapsed to a single column. (93673059)
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Jun ’22
Reply to SwiftUI Textfield Alert for macOS
macOS 13 Beta Release Notes SwiftUI New Features • You can now place a TextField in an Alert by using alert modifiers that accept a ViewBuilder . (64819930) I haven't tested it yet as I'm still using Monterey, but it should work according to the release notes. If you are looking for macOS 12 and earlier solutions, you can do something like this: Button("Tap Me") { let alert = NSAlert() alert.messageText = "Alert with text field"     alert.addButton(withTitle: "OK") // You can customise this text field, this is just an example.     alert.accessoryView = NSTextField(string: "Text")                  alert.runModal() }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Jun ’22
Reply to EditView Reference is Broken
The problem is that you have attached the .sheet modifier to the view inside of the ForEach, which means that every view has that sheet that presents its own version of EditView. Also the .contextMenu modifier should be attached to each view in the ForEach so it has access to the object that has been selected. I have changed your code so that this should (theoretically) work. // When the button in the context menu is tapped, the index of the corresponding object is stored in the selectedObjectIndex variable. // This triggers the sheet to appear with an unwrapped selectedObjectIndex which is used to get the object that is passed to the EditView. struct ContentView: View { @State private var objectList = [Object(title: "First", string: "Editor"), Object(title: "Second", string: "Addition"), Object(title: "Third", string: "Twelve")]     @State private var selectedObjectIndex: Int?         var body: some View {         NavigationView{             List{                 Section("Objects"){                     ForEach(objectList) { object in                         NavigationLink(destination: ObjectView(obj: object)){                             Text(object.title)                         } .contextMenu{ // move inside ForEach                     Button(action: {                         self.selectedObjectIndex = objectList.firstIndex(of: object)                     }){                         Text("Edit Item")                     }                 }                     }                 } .sheet(item: $selectedObjectIndex) { index in // move outside ForEach and use item initialiser                 EditView(obj: objectList[index])                 }             }             .listStyle(InsetGroupedListStyle())             .cornerRadius(10)             .navigationBarTitle("My List")         }     } }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Jun ’22
Reply to SwiftUI & Layout API. Extra trailing closure passed in call
The method behind the trailing closure accepts a closure as a parameter that can only return a single view. func callAsFunction<V>(_ content: () -> V) -> some View where V : View Since its not marked with @ViewBuilder, like most of the other SwiftUI view closures, you can only return one view. So your view will have to be declared like this if you want multiple views: MyStairsStack() { Group { Text("Hello, World!") Text("Hello, World!") Text("Hello, World!") } }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Jun ’22
Reply to SwiftUI & Layout API. Extra trailing closure passed in call
You need to add parentheses before you add the trailing closure, like this: MyStairsStack() { ... } Read through the documentation and it tells you how to initialise custom Layout instances, easier ways to do it as well as why.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Jun ’22
Reply to placeholderText Color
If you want the placeholderText property for SwiftUI's Color, you can access it like this: Color(uiColor: .placeholderText) You can also wrap this inside of an extension on Color for simpler code.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Jun ’22
Reply to SwiftUI: Does preferredColorScheme work on watch?
Dark Mode isn't supported on watchOS.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Jun ’22
Reply to Canceling an Edit: When to alert?
Here's my attempt at using the hasChanges property. It sort of combines the two approaches. See what you think – I'm not sure how well it works though. There is an entity called Item with three attributes: name: String, detail: String, amount: Int16 (for reproducibility). I used the template PersistenceController struct to inject the managedObjectContext into the views. struct ContentView: View {     @Environment(\.managedObjectContext) private var viewContext     @FetchRequest(sortDescriptors: []) private var items: FetchedResults<Item>     @State private var selectedItem: Item?     var body: some View {         NavigationStack {             List(items) { item in                 Button {                     selectedItem = item                 } label: {                     LabeledContent(item.title ?? "No name", value: item.amount, format: .number)                 }             }             .sheet(item: $selectedItem, content: EditView.init)             .toolbar {                 Button(action: addItem) {                     Label("Add Item", systemImage: "plus")                 }             }         }     }     private func addItem() {         withAnimation {             let newItem = Item(context: viewContext)             newItem.title = "New Item"             do {                 try viewContext.save()             } catch {                 fatalError("Failed to save: \(error.localizedDescription)")             }         }     } } struct EditView: View {     @Environment(\.dismiss) private var dismiss     @State private var showingCancelAlert = false     @State private var title: String     @State private var detail: String     @State private var amount: Int     let item: Item     init(item: Item) {         self.item = item         _title = State(wrappedValue: item.title ?? "")         _detail = State(wrappedValue: item.detail ?? "")         _amount = State(wrappedValue: Int(item.amount))     }     var body: some View {         NavigationStack {             Form {                 Section {                     TextField("Title", text: $title)                         .onSubmit {                             item.title = title                         }                     TextField("Description", text: $detail)                         .onSubmit {                             item.detail = detail                         }                 }                 Stepper("Amount: \(amount)", value: $amount) { _ in                     item.amount = Int16(amount)                 }             }             .navigationTitle("Edit Item")             .navigationBarTitleDisplayMode(.inline)             .toolbar {                 ToolbarItem(placement: .cancellationAction) {                     Button("Cancel", role: .cancel) {                         if item.hasChanges {                             showingCancelAlert = true                         } else {                             dismiss()                         }                     }                     .confirmationDialog("You have unsaved changes", isPresented: $showingCancelAlert) {                         Button("Discard Changes", role: .destructive, action: dismiss.callAsFunction)                     }                 }                 ToolbarItem(placement: .confirmationAction) {                     Button("Done", action: dismiss.callAsFunction)                         .disabled(!item.hasChanges)                 }             }         }         .interactiveDismissDisabled()     } }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Jun ’22
Reply to Canceling an Edit: When to alert?
I believe NSManagedObject has a hasChanges property so you can check that boolean value, however this requires you to update the object directly whenever the user changes something. The other option would be doing what @Claude31 suggested, or manually checking each property for a change between the current stored value and the one the user is modifying.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Jun ’22