Ash*_*lls 5 animation swiftui swiftui-scrollview
View在 aLazyVGrid和 an之间动画sHStack与它们之间的另一个视图(在本例中为 a Button),使用matchedGeometryEffect,效果很好:
请注意动画视图如何在“完成”按钮上方移动。
但是,当视图包含在 a 中时ScrollView,动画视图现在移动到中间视图的后面:
我已经尝试设置zIndex了的ScrollViews到> 0(或更多),但这似乎并没有改变什么都。
关于如何解决这个问题的任何想法?
人
struct Person: Identifiable, Equatable {
var id: String { name }
let name: String
var image: Image { Image(name) }
static var all: [Person] {
["Joe", "Kamala", "Donald", "Mike"].map(Person.init)
}
}
Run Code Online (Sandbox Code Playgroud)
内容视图
struct ContentView: View {
@State var people: [Person]
@State private var selectedPeople: [Person] = []
@Namespace var namespace
var body: some View {
VStack(alignment: .leading, spacing: 0) {
ScrollView(.horizontal) {
SelectedPeopleView(people: $selectedPeople, namespace: namespace) { person in
withAnimation(.easeOut(duration: 1)) {
selectPerson(person)
}
}
.background(Color.orange)
}
doneButton()
ScrollView(.vertical) {
PeopleView(people: people, namespace: namespace) { person in
withAnimation(.easeOut(duration: 1)) {
deselectPerson(person)
}
}
}
Spacer()
}
.padding()
}
func selectPerson(_ person: Person) {
_ = selectedPeople.firstIndex(of: person).map { selectedPeople.remove(at: $0)}
people.append(person)
}
func deselectPerson(_ person: Person) {
_ = people.firstIndex(of: person).map { people.remove(at: $0)}
selectedPeople.append(person)
}
func doneButton() -> some View {
Button("Done") {
}
.font(.title2)
.accentColor(.white)
.frame(maxWidth: .infinity)
.padding()
.background(Color.gray)
}
}
Run Code Online (Sandbox Code Playgroud)
所选人物视图
struct SelectedPeopleView: View {
@Binding var people: [Person]
let namespace: Namespace.ID
let didSelect: (Person) -> Void
var body: some View {
HStack {
ForEach(people) { person in
Button(action: { didSelect(person) } ) {
Text(person.name)
.padding(10)
.background(Color.yellow.cornerRadius(6))
.foregroundColor(.black)
.matchedGeometryEffect(id: person.id, in: namespace)
}
}
}
.frame(height: 80)
}
}
Run Code Online (Sandbox Code Playgroud)
人物视图
struct PeopleView: View {
let people: [Person]
let namespace: Namespace.ID
let didSelect: (Person) -> Void
let columns: [GridItem] = Array(repeating: .init(.flexible(minimum: .leastNormalMagnitude, maximum: .greatestFiniteMagnitude)), count: 2)
var body: some View {
LazyVGrid(columns: columns) {
ForEach(people) { person in
Button(action: { didSelect(person) }) {
person.image
.resizable()
.scaledToFill()
.layoutPriority(-1)
.clipped()
.aspectRatio(1, contentMode: .fit)
.cornerRadius(6)
}
.zIndex(zIndex(for: person))
.matchedGeometryEffect(id: person.id, in: namespace)
}
}
}
func zIndex(for person: Person) -> Double {
Double(people.firstIndex(of: person)!)
}
}
Run Code Online (Sandbox Code Playgroud)
这看起来像是 SwiftUI 中的一个错误,因为即使你用Color.clear任何高度代替 和 代替你的doneButton(或者甚至.padding是底部的某个高度ScrollView),效果也会是相同的。
从视图层次结构可以看出,两者之间没有任何内容ScrollView,并且图像的渲染在一个背景视图中执行
| 归档时间: |
|
| 查看次数: |
416 次 |
| 最近记录: |