【问题标题】:How do I keep clipped content of one subview from blocking gestures in underlying subviews with SwiftUI?如何使用 SwiftUI 防止一个子视图的剪辑内容阻止底层子视图中的手势?
【发布时间】:2020-09-28 01:23:59
【问题描述】:

我有一个主视图,其中包含一个 zStack,底部带有背景图像,上方是用户加载的图像,顶部有两个工具栏。工具栏位于视图的垂直顶部和底部。我希望这些工具栏显示为半透明,背景图像在大小和位置上与主视图的背景图像相匹配。如果用户拖动或缩放他们的图像以与工具栏重叠,则它应该被它们遮挡。为了实现这一点,我将这些工具栏视图构建为 zStack,并分别将相同的背景图像对齐到顶部或底部,并剪裁内容以匹配工具栏的高度。

我的问题是这些工具栏视图的剪辑内容会阻止底层用户加载图像上的手势。为了帮助可视化问题,我链接了主视图 (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

【问题讨论】:

标签: ios swift swiftui gesture zstack


【解决方案1】:

您可以在背景图片上设置allowsHitTesting(false)

或者,由于您不希望用户图像在工具栏后面可见,您也可以将 Rectangle 和工具栏添加到单个 VStack。

ZStack {
    Image("Background")
            .resizable()
            .scaledToFill()
    VStack {
        TopToolBar()
        Rectangle()
            .foregroundColor(.blue)
            ...
        BottomToolBar()
    }
}

【讨论】:

  • 设置allowsHitTesting(false) 有效!如果我将它们全部放在同一个 vStack 中,当图像被移动或调整大小时,它会停留在底部工具栏下方(需要),但会超过顶部工具栏(不需要)。
  • @Jesse 您可以将 .clipped() 添加到矩形。这将防止子视图被绘制到其边界之外。
  • @Jesse ...或使用顶部工具栏上的“.zIndex(1)”。这样工具栏将被绘制在顶部。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-12-06
  • 1970-01-01
  • 1970-01-01
  • 2020-07-21
  • 1970-01-01
  • 2019-11-27
  • 1970-01-01
相关资源
最近更新 更多