我正在使用 SwiftUI 的 PageTabViewStyle()
tabView 样式实现滑动选项卡 View ,类似于 Reddit 移动设备。顶部是所有变成蓝色的选项卡名称,就在一个小的 Capsule()
下方,它会移动到选定的选项卡。然而,当用户进入新选项卡时,我很难使用 matchedGeometryEffect()
使胶囊移动。
// The parent view
@State private var selectedTab: Category = .all
// [...]
VStack(spacing: 0) {
HistoryNavigationBar(selectedTab: $selectedTab)
TabView(selection: $selectedTab) {
ForEach(Category.allCases, id: \.self) { category in
HistoryList(category: category)
}
}
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
}
HistoryNavigationBar
的重要部分是:
@Namespace private var animation
// [...]
ForEach(History.Category.allCases, id: \.self) { category in
VStack(alignment: .leading, spacing: 5) {
Button(action: { selectedTab = category }) {
Text(category.rawValue.capitalized)
.foregroundColor(selectedTab == category ? .blue : .gray)
}
Capsule()
.frame(width: 20, height: 2)
.foregroundColor(selectedTab == category ? .blue : .clear)
}
}
我应该如何实现matchedGeometryEffect()
才能在每次选项卡更改时获得胶囊移动的所需效果?我尝试了与 matchedGeometryEffect()
的各种组合(将其放在胶囊后面、将胶囊放在 if 语句中等),但没有成功 – 每当我在选项卡之间滑动或单击时在其中一个选项卡名称上,胶囊会跳转到该选项卡。
最佳答案
您需要将 .matchedGeometryEffect 放在胶囊上,但仅在选择选项卡时绘制胶囊(使用 if 语句)。您还需要向胶囊添加动画。这是一个例子:
struct MGE: View {
@State var selectedTab: String = "one"
@Namespace private var namespace
enum Category: String, CaseIterable {
case one, two, three
}
var body: some View {
HStack(alignment: .top) {
ForEach(Category.allCases, id: \.self) { category in
VStack(alignment: .leading, spacing: 5) {
Button(action: { selectedTab = category.rawValue }) {
Text(category.rawValue.capitalized)
.foregroundColor(selectedTab == category.rawValue ? .blue : .gray)
}
if selectedTab == category.rawValue {
Capsule()
.frame(width: 20, height: 2)
.foregroundColor(.blue)
.matchedGeometryEffect(id: "capsule", in: namespace)
.animation(.spring())
}
}
}
}
}
}
关于ios - 在选项卡之间滑动时使 Capsule() 移动 -matchedGeometryEffect,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66001383/