我正在尝试使用Swift 5.3制作一个VGrid
,但是唯一可以点击的区域是矩形的上部。其他答案建议使用contentShape
,但我也无法使之工作。如何使整个框架可轻敲?下面的代码:
import SwiftUI
import Combine
import Foundation
struct Item: Codable, Identifiable, Equatable {
var id: Int
var name: String
}
final class UserData: ObservableObject {
@Published var items = Bundle.main.decode([Item].self, from: "data.json")
}
struct ContentView: View {
@State var itemID = Item.ID()
@StateObject var userData = UserData()
let columns = [
GridItem(.adaptive(minimum: 118))
]
var body: some View {
NavigationView {
ScrollView {
LazyVGrid(columns: columns) {
ForEach(userData.items) { item in
NavigationLink(destination: ContentDetail(itemID: item.id - 1)) {
ContentRow(item: item)
}
}
}
}
}
}
}
struct ContentRow: View {
var item: Item
var body: some View {
VStack {
GeometryReader { geo in
ZStack{
VStack(alignment: .trailing) {
Text(item.name)
.font(.caption)
}
}
.padding()
.foregroundColor(Color.primary)
.frame(width: geo.size.width, height: 120)
.border(Color.primary, width: 2)
.cornerRadius(5)
.contentShape(Rectangle())
}
}
}
}
struct ContentDetail: View {
@State var itemID = Item.ID()
@StateObject var userData = UserData()
var body: some View {
Text(userData.items[itemID].name)
}
}
extension Bundle {
func decode<T: Decodable>(_ type: T.Type, from file: String, dateDecodingStrategy: JSONDecoder.DateDecodingStrategy = .deferredToDate, keyDecodingStrategy: JSONDecoder.KeyDecodingStrategy = .useDefaultKeys) -> T {
guard let url = self.url(forResource: file, withExtension: nil) else {
fatalError("Failed to locate \(file) in bundle.")
}
guard let data = try? Data(contentsOf: url) else {
fatalError("Failed to load \(file) from bundle.")
}
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = dateDecodingStrategy
decoder.keyDecodingStrategy = keyDecodingStrategy
do {
return try decoder.decode(T.self, from: data)
} catch DecodingError.keyNotFound(let key, let context) {
fatalError("Failed to decode \(file) from bundle due to missing key '\(key.stringValue)' not found – \(context.debugDescription)")
} catch DecodingError.typeMismatch(_, let context) {
fatalError("Failed to decode \(file) from bundle due to type mismatch – \(context.debugDescription)")
} catch DecodingError.valueNotFound(let type, let context) {
fatalError("Failed to decode \(file) from bundle due to missing \(type) value – \(context.debugDescription)")
} catch DecodingError.dataCorrupted(_) {
fatalError("Failed to decode \(file) from bundle because it appears to be invalid JSON")
} catch {
fatalError("Failed to decode \(file) from bundle: \(error.localizedDescription)")
}
}
}
还有JSON部分:
[
{
"id": 1,
"name": "Example data",
},
{
"id": 2,
"name": "Example data 2",
}
]
感谢您的帮助。这可能是SwiftUI中的错误吗?
答案 0 :(得分:0)
尝试将contentShape放在ContentRow的最外层VStack上。您需要将contentShape放在展开的视图上以填充其父级(或父级),在您的情况下,我认为这是GeometryReader。 GeometryReader内部的所有视图都会缩小以适合其内容,因此您的contentShape矩形在此无济于事。
答案 1 :(得分:0)
由于您始终设置了高度,因此可以简单地删除GeometryReader:
struct ContentRow: View {
var item: Item
var body: some View {
VStack {
ZStack{
VStack(alignment: .trailing) {
Text(item.name)
.font(.caption)
}
}
.padding()
.foregroundColor(Color.primary)
.frame(width: 120, height: 120)
.border(Color.primary, width: 2)
.cornerRadius(5)
.background(Color.red)
}
}
}