Post

Replies

Boosts

Views

Activity

Improve display grid of SwiftUI Charts
Hello all! I'm implementing a view that shows a grid of different histograms to show a final report to the user. It could have ~100 rows and ~10 columns. I'm using a LazyVGrid and it looks like: Note: the example contains only 3 rows. It takes less than a second to render the grid, but you can feel the app is blocked for a few ms. I was wonder if some of you know how to render asynchronously the chart views so, at least, not block the interface. Thanks!
0
0
614
Nov ’23
View like the camera app
Hello all, I would like to understand how to create a SwiftUI View like the official camera app. When the device orientation changes, the view is not animating, and the buttons just rotate (4:3, 1x...). The camera app view is compose by flash and live buttons, camera preview, config buttons, and big button to shot the photo. In portrait, it is from top to bottom, in landscape, from left to right. Also, when the last pictures view is shown, it is adapted to the current orientation, like if the camera preview view was rendered in the same device orientation. Ideas? Thanks!
2
0
3.2k
Oct ’23
NavigationSplitView + FetchResults
Hello, I'm using a NavigationSplitView and feeding the sidebar using FetchResults. In the detail view, the user can update the field name of the entity and then, the sidebar becomes useless, selecting random rows and hiding some of them, like these pictures: I could reproduce the issue using a sample project. If you want to have the project to test it, create a simple project on Xcode: iOS app / +Use Core Data & +Host in CloudKit Then, add a field "name String?" in the Entity and use this code in ContentView.swift: import SwiftUI import CoreData extension Binding { public func replaceNil<T>(_ defaultValue: T) -> Binding<T> where Value == Optional<T> { return .init { wrappedValue ?? defaultValue } set: { wrappedValue = $0 } } } struct Header: View { @ObservedObject var item: Item var body: some View { VStack { if let name = item.name, !name.isEmpty { Text(name) } else { Text("---") .foregroundColor(.secondary) } } } } struct ItemDetail: View { @ObservedObject var item: Item var body: some View { VStack { Spacer() if let timestamp = item.timestamp { Text(timestamp, formatter: itemFormatter) } else { Text("---") .foregroundColor(.secondary) } Button("Update") { item.timestamp = Date.now } TextField("Name", text: $item.name.replaceNil("")) Spacer() } .padding() } } struct ContentView: View { @Environment(\.managedObjectContext) private var viewContext @State private var selected: Item.ID? @FetchRequest( sortDescriptors: [ SortDescriptor(\.name, order: .forward), SortDescriptor(\.timestamp, order: .forward), ], animation: .default) private var items: FetchedResults<Item> var body: some View { NavigationSplitView { List(selection: $selected) { ForEach(items) { item in Header(item: item) } .onDelete(perform: deleteItems) } .toolbar { ToolbarItem(placement: .navigationBarTrailing) { EditButton() } ToolbarItem { Button(action: addItem) { Label("Add Item", systemImage: "plus") } } } } detail: { if let selected, let index = items.firstIndex(where: { $0.id == selected }) { ItemDetail(item: items[index]) } else { Text("Select something") } } } private func addItem() { withAnimation { do { let newItem = Item(context: viewContext) newItem.name = "Name" newItem.timestamp = Date() try viewContext.save() selected = newItem.id } catch { let nsError = error as NSError fatalError("Unresolved error \(nsError), \(nsError.userInfo)") } } } private func deleteItems(offsets: IndexSet) { withAnimation { offsets.map { items[$0] }.forEach(viewContext.delete) do { try viewContext.save() } catch { let nsError = error as NSError fatalError("Unresolved error \(nsError), \(nsError.userInfo)") } } } } private let itemFormatter: DateFormatter = { let formatter = DateFormatter() formatter.dateStyle = .short formatter.timeStyle = .medium return formatter }() struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView().environment(\.managedObjectContext, PersistenceController.preview.container.viewContext) .previewInterfaceOrientation(.landscapeLeft) } } Any ideas?
2
0
1.1k
Feb ’23
accessibility PLAY button: no speak or add a delay?
Hello, I'm developing an app that plays a short audio when you push a button. When I'm testing VoiceOver and "push" the button, the voice says "Play button, playing..." over the audio I'm playing, and it is impossible to listen to it. What do you think is the best approach? I would like to add a delay to my audio, but I could not see a callback when the voiceOver said the sentence. Is it correct to remove the accessibility label for this kind of buttons (play/pause/stop)? Thanks!
2
0
1.1k
Jan ’22
Improve display grid of SwiftUI Charts
Hello all! I'm implementing a view that shows a grid of different histograms to show a final report to the user. It could have ~100 rows and ~10 columns. I'm using a LazyVGrid and it looks like: Note: the example contains only 3 rows. It takes less than a second to render the grid, but you can feel the app is blocked for a few ms. I was wonder if some of you know how to render asynchronously the chart views so, at least, not block the interface. Thanks!
Replies
0
Boosts
0
Views
614
Activity
Nov ’23
View like the camera app
Hello all, I would like to understand how to create a SwiftUI View like the official camera app. When the device orientation changes, the view is not animating, and the buttons just rotate (4:3, 1x...). The camera app view is compose by flash and live buttons, camera preview, config buttons, and big button to shot the photo. In portrait, it is from top to bottom, in landscape, from left to right. Also, when the last pictures view is shown, it is adapted to the current orientation, like if the camera preview view was rendered in the same device orientation. Ideas? Thanks!
Replies
2
Boosts
0
Views
3.2k
Activity
Oct ’23
NavigationSplitView + FetchResults
Hello, I'm using a NavigationSplitView and feeding the sidebar using FetchResults. In the detail view, the user can update the field name of the entity and then, the sidebar becomes useless, selecting random rows and hiding some of them, like these pictures: I could reproduce the issue using a sample project. If you want to have the project to test it, create a simple project on Xcode: iOS app / +Use Core Data & +Host in CloudKit Then, add a field "name String?" in the Entity and use this code in ContentView.swift: import SwiftUI import CoreData extension Binding { public func replaceNil<T>(_ defaultValue: T) -> Binding<T> where Value == Optional<T> { return .init { wrappedValue ?? defaultValue } set: { wrappedValue = $0 } } } struct Header: View { @ObservedObject var item: Item var body: some View { VStack { if let name = item.name, !name.isEmpty { Text(name) } else { Text("---") .foregroundColor(.secondary) } } } } struct ItemDetail: View { @ObservedObject var item: Item var body: some View { VStack { Spacer() if let timestamp = item.timestamp { Text(timestamp, formatter: itemFormatter) } else { Text("---") .foregroundColor(.secondary) } Button("Update") { item.timestamp = Date.now } TextField("Name", text: $item.name.replaceNil("")) Spacer() } .padding() } } struct ContentView: View { @Environment(\.managedObjectContext) private var viewContext @State private var selected: Item.ID? @FetchRequest( sortDescriptors: [ SortDescriptor(\.name, order: .forward), SortDescriptor(\.timestamp, order: .forward), ], animation: .default) private var items: FetchedResults<Item> var body: some View { NavigationSplitView { List(selection: $selected) { ForEach(items) { item in Header(item: item) } .onDelete(perform: deleteItems) } .toolbar { ToolbarItem(placement: .navigationBarTrailing) { EditButton() } ToolbarItem { Button(action: addItem) { Label("Add Item", systemImage: "plus") } } } } detail: { if let selected, let index = items.firstIndex(where: { $0.id == selected }) { ItemDetail(item: items[index]) } else { Text("Select something") } } } private func addItem() { withAnimation { do { let newItem = Item(context: viewContext) newItem.name = "Name" newItem.timestamp = Date() try viewContext.save() selected = newItem.id } catch { let nsError = error as NSError fatalError("Unresolved error \(nsError), \(nsError.userInfo)") } } } private func deleteItems(offsets: IndexSet) { withAnimation { offsets.map { items[$0] }.forEach(viewContext.delete) do { try viewContext.save() } catch { let nsError = error as NSError fatalError("Unresolved error \(nsError), \(nsError.userInfo)") } } } } private let itemFormatter: DateFormatter = { let formatter = DateFormatter() formatter.dateStyle = .short formatter.timeStyle = .medium return formatter }() struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView().environment(\.managedObjectContext, PersistenceController.preview.container.viewContext) .previewInterfaceOrientation(.landscapeLeft) } } Any ideas?
Replies
2
Boosts
0
Views
1.1k
Activity
Feb ’23
accessibility PLAY button: no speak or add a delay?
Hello, I'm developing an app that plays a short audio when you push a button. When I'm testing VoiceOver and "push" the button, the voice says "Play button, playing..." over the audio I'm playing, and it is impossible to listen to it. What do you think is the best approach? I would like to add a delay to my audio, but I could not see a callback when the voiceOver said the sentence. Is it correct to remove the accessibility label for this kind of buttons (play/pause/stop)? Thanks!
Replies
2
Boosts
0
Views
1.1k
Activity
Jan ’22