在 ScrollView 中使用matchedGeometryEffect 动画的问题
Posted
技术标签:
【中文标题】在 ScrollView 中使用matchedGeometryEffect 动画的问题【英文标题】:Issue using matchedGeometryEffect animation in ScrollView 【发布时间】:2020-08-18 20:18:06 【问题描述】:使用matchedGeometryEffect
在LazyVGrid
和HStack
之间使用另一个视图(在本例中为Button
)对View
s 进行动画处理,效果很好:
注意动画视图是如何移动到完成按钮之上的。
但是,当视图包含在 ScrollView
中时,动画视图现在移动到 中间视图之后:
我尝试将ScrollView
s 的zIndex
设置为> 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)
内容视图
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)
SelectedPeopleView
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)
人物视图
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)!)
【问题讨论】:
【参考方案1】:这看起来像 SwiftUI 中的一个错误,因为即使您将任何高度的 Color.clear
代替而不是您的 doneButton
(或者甚至是底部 ScrollView
的某个高度的 .padding
),效果也会一样。
从视图层次结构中可以看出,两个ScrollView
之间没有任何内容,并且图像的渲染是在一个背景视图中执行的
【讨论】:
谢谢 - 我也找到了。引发了 Apple 的错误 (FB8458770) 在 ios 15.1 和 swiftUI 3 上遇到同样的问题 :( 有什么解决办法吗?以上是关于在 ScrollView 中使用matchedGeometryEffect 动画的问题的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Xcode 6.3 中使用 AutoLayout 创建 ScrollView
如何使用 SnapKit 在 ScrollView 中居中按钮数组
在 ScrollView 中使用 GeometryReader 的 SwiftUI 布局
无法在 SlidingUpPanelLayout Xamarin Android 中使用 ScrollView 布局