我有一个
WineInfoView
,它显示特定葡萄酒的一系列图像。水平滚动中的最后一个“图像”是一个空白图像,点击该图像时会显示用户的相机胶卷并允许他们添加新图像。
当我在
HorizontalImageScrollView()
中测试它时,我正确地将新图像放置在最后一个“图像”之前,但在“WineInfoView”中测试或在我的设备上运行应用程序时可以看到更改。
这是两个视图的代码:
WineInfoView
struct WineInfoView: View {
//ADD MODEL HERE
@State var wine: Wine
var body: some View {
HorizontalImageScrollView(wine: $wine)
}
}
水平图像滚动:
struct HorizontalImageScrollView: View {
@Binding var wine: Wine
//For selecting / adding phtotos
@State var photoPickerPresented: Bool = false
@State var cameraPresente: Bool = false
@State private var selectedItem: PhotosPickerItem?
@State var image: UIImage?
var body: some View {
ScrollView(.horizontal, content: {
//parse through images that exist
HStack {
ForEach(wine.images, id: \.self) { image in
Image(uiImage: image)
.resizable()
.scaledToFill()
.frame(width: 175, height: 250)
.clipShape(RoundedRectangle(cornerRadius: 25.0))
.padding()
}
////////////////////////////////////////////////////////////////////////////
///// PHOTO PICKER
//empty "Image" to add more pictures
PhotosPicker(selection: $selectedItem, label: {
ZStack {
Color(uiColor: UIColor(rgb: 0xEDEDE9))
.frame(width: 175, height: 250)
.clipShape(RoundedRectangle(cornerRadius: 25.0))
.padding([.leading,.trailing])
Image(systemName: "plus.circle.fill")
}
})
.onChange(of: selectedItem) {
Task {
if let data = try? await selectedItem?.loadTransferable(type: Data.self) {
image = UIImage(data: data)
//add image to local object
wine.images.append(image!)
//update record in DB
updateWineRecordPhotos(wine.images)
} else {
print("Failed to load the image")
}
}
}
////////////////////////////////////////////////////////////////////////////
}
})
}
}
有人可以解释为什么更改没有显示在
WineInfoView
中吗?
您应该在您的
WineInfoView
中实例化一个 wine 对象,
例如:@State private var wine: Wine = Wine(.... ,images: [])
,这样就可以在WineInfoView
中添加和显示图像。
同时避免使用强制展开
!
,例如:wine.images.append(image!)
,请参阅代码更新。
这是我的测试代码,当我选择照片而不是视频等时,它对我来说效果很好......
在 MacOS 14.3 上,使用 Xcode 15.2,在真实的 ios 17 设备(不是预览版)和 macCatalyst 上进行测试。在旧系统上可能会有所不同。
// for testing
struct Wine: Identifiable {
let id = UUID()
var name: String
var images: [UIImage]
// ....
}
struct WineInfoView: View {
@State private var wine: Wine = Wine(name: "Chateau Cardboard", images: []) // <--- here
var body: some View {
HorizontalImageScrollView(wine: $wine)
}
}
struct HorizontalImageScrollView: View {
@Binding var wine: Wine
//For selecting / adding phtotos
@State var photoPickerPresented: Bool = false
@State var cameraPresente: Bool = false
@State private var selectedItem: PhotosPickerItem?
@State var image: UIImage? // <--- not used
var body: some View {
ScrollView(.horizontal, content: {
//parse through images that exist
HStack {
ForEach(wine.images, id: \.self) { image in
Image(uiImage: image)
.resizable()
.scaledToFill()
.frame(width: 175, height: 250)
.clipShape(RoundedRectangle(cornerRadius: 25.0))
.padding()
}
//empty "Image" to add more pictures
PhotosPicker(selection: $selectedItem, label: {
ZStack {
Color(uiColor: .lightGray)
.frame(width: 175, height: 250)
.clipShape(RoundedRectangle(cornerRadius: 25.0))
.padding([.leading,.trailing])
Image(systemName: "plus.circle.fill")
}
})
.onChange(of: selectedItem) {
Task {
if let data = try? await selectedItem?.loadTransferable(type: Data.self),
let img = UIImage(data: data) {
image = img
//add image to local object
wine.images.append(img)
//update record in DB
// updateWineRecordPhotos(wine.images) // for testing
} else {
print("----> Failed to load the image")
}
}
}
}
})
}
}
编辑-1:
如果您将
wine
对象从父视图传递到 WineInfoView
,
然后使用 Binding
,例如:
struct ContentView: View {
@State private var wine: Wine = Wine(name: "Chateau Cardboard", images: []) // <--- here
var body: some View {
WineInfoView(wine: $wine) // <--- here
}
}
struct WineInfoView: View {
@Binding var wine: Wine // <--- here
var body: some View {
HorizontalImageScrollView(wine: $wine)
}
}
struct HorizontalImageScrollView: View {
@Binding var wine: Wine // <--- here
// .....