如何使用 SwiftUI 阻止一个子视图的剪辑内容阻止底层子视图中的手势?
How do I keep clipped content of one subview from blocking gestures in underlying subviews with SwiftUI?
我有一个主视图,它由一个 zStack 组成,底部有一个背景图像,上面有一个用户加载的图像,顶部有两个工具栏。工具栏位于视图的垂直顶部和底部。我希望这些工具栏显示为半透明,背景图像在大小和位置上与主视图的背景图像相匹配。如果用户拖动或缩放他们的图像以与工具栏重叠,它应该被它们遮住。为此,我将这些工具栏视图构建为 zStacks,具有分别与顶部或底部对齐的相同背景图像,并裁剪内容以匹配工具栏的高度。
我的问题是那些工具栏视图的裁剪内容会阻止底层用户加载图像上的手势。为了帮助可视化问题,我链接了主视图 (MockScoringView) 的调试视图层次结构的屏幕截图。
这是主视图的代码:
GeometryReader { geometry in
ZStack {
Rectangle()
.foregroundColor(.blue)
.frame(width: geometry.size.width, height: geometry.size.height)
.offset(x: self.baseOffset.width + self.newOffset.width, y: self.baseOffset.height + self.newOffset.height)
.scaleEffect(self.scale)
.gesture(DragGesture()
.onChanged { value in
self.newOffset.width = value.translation.width / self.scale
self.newOffset.height = value.translation.height / self.scale
}
.onEnded { value in
self.baseOffset.width += self.newOffset.width
self.baseOffset.height += self.newOffset.height
self.newOffset = CGSize.zero
}
)
VStack(spacing: 0) {
MockTopToolbarView()
Spacer()
MockBottomToolbarView()
}
}
}
以及顶部工具栏视图的代码,与底部的非常相似:
ZStack {
Image("Background")
.resizable()
.scaledToFill()
.frame(height: 56, alignment: .top)
.clipped()
Rectangle()
.foregroundColor(.toolbarGray)
.frame(height: 56)
}
我想修改工具栏视图背景的内容,这样它们就不会阻止手势到达用户加载的图像。
Debug View Hierarchy
您可以在背景图片上设置allowsHitTesting(false)
。
或者,由于您不希望用户图像在工具栏后面可见,您也可以将矩形和工具栏添加到单个 VStack。
ZStack {
Image("Background")
.resizable()
.scaledToFill()
VStack {
TopToolBar()
Rectangle()
.foregroundColor(.blue)
...
BottomToolBar()
}
}
我有一个主视图,它由一个 zStack 组成,底部有一个背景图像,上面有一个用户加载的图像,顶部有两个工具栏。工具栏位于视图的垂直顶部和底部。我希望这些工具栏显示为半透明,背景图像在大小和位置上与主视图的背景图像相匹配。如果用户拖动或缩放他们的图像以与工具栏重叠,它应该被它们遮住。为此,我将这些工具栏视图构建为 zStacks,具有分别与顶部或底部对齐的相同背景图像,并裁剪内容以匹配工具栏的高度。
我的问题是那些工具栏视图的裁剪内容会阻止底层用户加载图像上的手势。为了帮助可视化问题,我链接了主视图 (MockScoringView) 的调试视图层次结构的屏幕截图。
这是主视图的代码:
GeometryReader { geometry in
ZStack {
Rectangle()
.foregroundColor(.blue)
.frame(width: geometry.size.width, height: geometry.size.height)
.offset(x: self.baseOffset.width + self.newOffset.width, y: self.baseOffset.height + self.newOffset.height)
.scaleEffect(self.scale)
.gesture(DragGesture()
.onChanged { value in
self.newOffset.width = value.translation.width / self.scale
self.newOffset.height = value.translation.height / self.scale
}
.onEnded { value in
self.baseOffset.width += self.newOffset.width
self.baseOffset.height += self.newOffset.height
self.newOffset = CGSize.zero
}
)
VStack(spacing: 0) {
MockTopToolbarView()
Spacer()
MockBottomToolbarView()
}
}
}
以及顶部工具栏视图的代码,与底部的非常相似:
ZStack {
Image("Background")
.resizable()
.scaledToFill()
.frame(height: 56, alignment: .top)
.clipped()
Rectangle()
.foregroundColor(.toolbarGray)
.frame(height: 56)
}
我想修改工具栏视图背景的内容,这样它们就不会阻止手势到达用户加载的图像。
Debug View Hierarchy
您可以在背景图片上设置allowsHitTesting(false)
。
或者,由于您不希望用户图像在工具栏后面可见,您也可以将矩形和工具栏添加到单个 VStack。
ZStack {
Image("Background")
.resizable()
.scaledToFill()
VStack {
TopToolBar()
Rectangle()
.foregroundColor(.blue)
...
BottomToolBar()
}
}