The goal is to pass dynamic content into a single modal, as if it was a detailed view:
import SwiftUI
struct Item {
let number: String
let id = UUID()
}
class ItemSet: ObservableObject {
@Published var collection: [Item]
init() {
self.collection = []
for index in 1...100 {
self.collection.append(Item(number: "\(index)"))
}
}
}
struct ContentView: View {
@ObservedObject var items: ItemSet
@State private var selectedItem: Item?
@State private var showingFull = false
init() {
self.items = ItemSet()
self.selectedItem = nil
}
var columns = [
GridItem(.adaptive(minimum: 150), spacing: 5.0)
]
var body: some View {
ScrollView {
LazyVGrid(columns: columns) {
ForEach(items.collection, id: \.id) {item in
Text(item.number)
.frame(height: 100)
.onTapGesture {
self.selectedItem = item
self.showingFull = true
}
.sheet(isPresented: $showingFull) {
if let item = selectedItem {
Text(item.number)
}
}
}
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
For some reason, the first time you tap a cell, the modal is empty, as if the state was not updated before rendering the modal content, but any time after that works as intended. Am I missing something obvious or should I file a radar?
One possible solution I found is moving the sheet and state to be their own structs:
struct ContentView: View {
@ObservedObject var items: ItemSet
init() {
self.items = ItemSet()
}
var columns = [
GridItem(.adaptive(minimum: 150), spacing: 5.0)
]
var body: some View {
ScrollView {
LazyVGrid(columns: columns) {
ForEach(items.collection, id: \.id) {item in
TextItem(item: item)
}
}
}
}
}
struct TextItem: View {
let item: Item
@State private var showingFull = false
var body: some View {
Text(item.number)
.frame(height: 100)
.onTapGesture {
self.showingFull = true
}
.sheet(isPresented: $showingFull) {
Text(item.number)
}
}
}
I don't know how "correct" this solution is in terms of being proper SwiftUI, but I haven't noticed any performance issues when used inside a more complex and heavy layout.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With