目标:从列表传递图像数据->类似于苹果照片应用程序的缩放动画细节。
我所做的:使用了匹配的几何效果,效果非常好。
问题:我只能硬编码,因为我在同一个ContentView((上有List((和Detail((,我不知道如何传递数据List->详细信息
感谢您的意见!
import SwiftUI
struct Grid: View {
let namespace: Namespace.ID
var body: some View {
List{
Image("cover")
.resizable()
.frame(width: 50, height: 50)
.cornerRadius(4)
.padding()
.matchedGeometryEffect(id: "animation", in: namespace)
Image("cover2")
.resizable()
.frame(width: 50, height: 50)
.cornerRadius(4)
.padding()
.matchedGeometryEffect(id: "animation", in: namespace)
}
}
}
struct Detail: View {
let namespace: Namespace.ID
var body: some View {
Image("cover")
.resizable()
.aspectRatio(contentMode: .fit)
.cornerRadius(10)
.padding(40)
.matchedGeometryEffect(id: "animation", in: namespace)
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color(#colorLiteral(red: 0.234857142, green: 0.043259345, blue: 0.04711621255, alpha: 1)))
}
}
struct ContentView: View {
@Namespace private var ns
@State private var showDetails: Bool = false
var body: some View {
ZStack {
Spacer()
if showDetails {
Detail(namespace: ns)
}
else {
Grid(namespace: ns)
}
}
.onTapGesture {
withAnimation(.spring()) {
showDetails.toggle()
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
您可以使用@EnvironmentObject
属性包装器在视图之间传递数据。为此,您需要具有已发布属性的可观察对象类(例如CoverData
(。
此外,对于要分组的视图(例如图像名称(,您应该使用matchedGeometryEffect
的唯一id
我对你的代码做了最小的修改,看看这是否是你想要的:
import SwiftUI
class CoverData: ObservableObject {
@Published var images = ["cover", "cover2"]
@Published var selected = ""
@Published var showDetails: Bool = false
}
struct Grid: View {
@EnvironmentObject var coverData: CoverData
let namespace: Namespace.ID
var body: some View {
List {
ForEach(coverData.images.indices) { index in
let image = coverData.images[index]
Image(image)
.resizable()
.frame(width: 50, height: 50)
.cornerRadius(4)
.padding()
.matchedGeometryEffect(id: image, in: namespace)
.onTapGesture {
coverData.selected = image
withAnimation(.spring()) {
coverData.showDetails.toggle()
}
}
}
}
}
}
struct Detail: View {
@EnvironmentObject var coverData: CoverData
let namespace: Namespace.ID
var body: some View {
Image(coverData.selected)
.resizable()
.aspectRatio(contentMode: .fit)
.cornerRadius(10)
.padding(40)
.matchedGeometryEffect(id: coverData.selected, in: namespace)
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color(#colorLiteral(red: 0.234857142, green: 0.043259345, blue: 0.04711621255, alpha: 1)))
}
}
struct ContentView: View {
@Namespace private var ns
@StateObject private var coverData = CoverData()
var body: some View {
ZStack {
Spacer()
if coverData.showDetails {
Detail(namespace: ns)
.onTapGesture {
withAnimation(.spring()) {
coverData.showDetails.toggle()
}
}
}
else {
Grid(namespace: ns)
}
}
.environmentObject(coverData)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}