ios - 当视图嵌入在按钮中时,SwiftUI 匹配几何效果“匹配几何组中的多个插入视图对警告”
问题描述
当用户选择不同的选项卡时,我想实现下划线从一个选项卡移动到另一个选项卡的幻灯片动画
我正在使用matchedGeometryEffect,如下所示:
HStack(spacing: 15) {
ForEach(categories, id: \.self) { category in
let isSelected = selectedVal == category
Button {
withAnimation {
selectedVal = category
}
} label: {
VStack(spacing: 4) {
Text(category)
.frame(width: 100)
if isSelected {
RoundedRectangle(cornerRadius: 5)
.frame(width: 50, height: 2)
.matchedGeometryEffect(id: "Category", in: animation, isSource: isSelected)
}
}
}
}
}
这种方法适用于警告Multiple inserted views in matched geometry group Pair<String, ID>(first: "Category", second: SwiftUI.Namespace.ID(id: 10)) have isSource: true, results are undefined.
当我RoundedRectangle
从Button
警告中提取时消失:
HStack(spacing: 15) {
ForEach(categories, id: \.self) { category in
let isSelected = selectedVal == category
VStack(spacing: 4) {
Button(category) {
withAnimation {
selectedVal = category
}
}
if isSelected {
RoundedRectangle(cornerRadius: 5)
.frame(width: 50, height: 2)
.matchedGeometryEffect(id: "Category", in: animation, isSource: isSelected)
}
}
}
}
我怀疑这与Button
在第一个解决方案中没有从视图层次结构中删除有关,因此仍然持有RoundedRectangle
对 matchGeometry 的引用,因为你不能让源视图“可见”,但我会虽然isSource
被设置到选定的状态就可以解决这个问题。有没有解释为什么我在第一种情况下收到警告?
解决方案
问题是您可以一次仅在一个视图中设置具有相同命名空间的 matchedgeometryeffect。以便 SwiftUI 可以确定要为哪个对象设置动画。这里是你设置几何效果所有三个具有相同命名空间的视图,所以 swiftUI 无法弄清楚如何为所有视图设置动画和布局。
struct ContentView: View {
enum Tab: String {
case one
case two
case three
}
@State private var selected: Tab = .one
@Namespace private var tabNameSpace
var body: some View {
ZStack {
HStack(spacing: 32) {
ZStack {
if selected == .one {
Color.red
.frame(width: 100, height: 50)
.matchedGeometryEffect(id: "namespace", in: tabNameSpace)
}
Text(Tab.one.rawValue)
.frame(width: 100, height: 50)
.onTapGesture {
withAnimation(.spring()) {
selected = .one
}
}
}
ZStack {
if selected == .two {
Color.red
.frame(width: 100, height: 50)
.matchedGeometryEffect(id: "namespace", in: tabNameSpace)
}
Text(Tab.two.rawValue)
.frame(width: 100, height: 50)
.onTapGesture {
withAnimation(.spring()) {
selected = .two
}
}
}
ZStack {
if selected == .three {
Color.red
.frame(width: 100, height: 50)
.matchedGeometryEffect(id: "namespace", in: tabNameSpace)
}
Text(Tab.three.rawValue)
.frame(width: 100, height: 50)
.onTapGesture {
withAnimation(.spring()) {
selected = .three
}
}
}
}
}
}
}
推荐阅读
- python - 为什么 beautifulsoup 代码部分返回 NaN?
- groovy - Vaadin:升级 8.13.3 后编译出错
- symfony - Symfony - ParamConverter 出现问题,几天都没有触摸我的代码
- php - 来自其他模型的 Laravel 模型急切加载条件
- kivy - 循环内的 Kivy 小部件
- blockchain - 如何分析 Solana 区块链上已确认交易中的 tokenBalances?
- php - 通过 Composer 在 Laravel 8 中添加 CKEditor
- excel - 使用 Excel 的两个选项卡中的列的 INDEX MATCH 函数问题
- css - 当父母被点击时隐藏 div 但当孩子被点击时,则不是
- android - Android Jetpack Compose - 如何在图像上显示徽章?