我正在构建类似于 Instagram 故事的东西。但无论我尝试什么,选项卡视图标签或点击手势都有效。我无法让他们一起工作。目的是如果我点击视图的左侧或右侧,它将跳转到同一故事模型的另一个故事。如果我滚动选项卡视图,它将跳转到另一个 StoryModel。
这是我尝试过的扩展
struct OnTap: ViewModifier {
let response: (CGPoint) -> Void
@State private var location: CGPoint = .zero
func body(content: Content) -> some View {
content
.onTapGesture {
response(location)
}
.simultaneousGesture(
DragGesture(minimumDistance: 0)
.onEnded { location = $0.location }
)
}
}
extension View {
func onTapGesture(_ handler: @escaping (CGPoint) -> Void) -> some View {
self.modifier(OnTap(response: handler))
}
}
struct OnTapAndTagAction: ViewModifier {
let onTap: (CGPoint) -> Void
let index: Int
func body(content: Content) -> some View {
content
.overlay(
Rectangle()
.fill(Color.clear)
.onTapGesture { tapLocation in
onTap(tapLocation)
}
)
.tag(index)
}
}
extension View {
func onTapGestureAndTag(index: Int, _ handler: @escaping (CGPoint) -> Void) -> some View {
self.modifier(OnTapAndTagAction(onTap: handler, index: index))
}
}
这就是我使用它的方式
struct StoryDetailView: View {
ZStack {
Color.storyNotchPurple
.edgesIgnoringSafeArea(.top)
TabView(selection: $selectedStoryId) {
Color.storyNotchPurple.edgesIgnoringSafeArea(.top)
ForEach(storyModelArray.indices, id: \.self) { index in
GeometryReader {...}
.onTapGestureAndTag(index: index) { tapLocation in
if tapLocation.x < screenWidth / 2 {
if currentStoryIndex > 1 {
currentStoryIndex -= 1
}
} else {
if currentStoryIndex < progressCount {
currentStoryIndex += 1
}
}
}
}
}
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
.edgesIgnoringSafeArea(.top)
}
我没有使用点击手势,而是使用按钮和 z 索引
HStack {
Button(action: {
if currentStoryIndex > 1 {
currentStoryIndex -= 1
}
}) {
Color.clear
.contentShape(Rectangle())
.frame(width: screenWidth / 2, height: g.size.height - 100)
}
.buttonStyle(PlainButtonStyle())
Button(action: {
if currentStoryIndex < progressCount {
currentStoryIndex += 1
}
}) {
Color.clear
.contentShape(Rectangle())
.frame(width: screenWidth / 2, height: g.size.height - 100)
}
.buttonStyle(PlainButtonStyle())
}
.zIndex(1)