【问题标题】:How to disable user interaction on SwiftUI view?如何在 SwiftUI 视图上禁用用户交互?
【发布时间】:2020-01-13 17:20:07
【问题描述】:

假设我有一个如下所示的 SwiftUI 视图层次结构:

ZStack() {
    ScrollView {
        ...
    }
    Text("Hello.")
}

Text 视图阻止触摸事件到达底层ScrollView

使用 UIKit,我会使用 .isUserInteractionEnabled 之类的东西来控制它,但我找不到任何使用 SwiftUI 的方法。

我尝试在文本视图中添加Gesture.noneGestureMask,但这似乎不起作用。

我希望我在这里遗漏了一些明显的东西,因为我需要在滚动视图的顶部放置一些状态信息。

【问题讨论】:

  • 在 SwiftUI 的“原始”和您描述的异常需要之间,如果您遗漏了一些明显的东西,我会感到惊讶 - 它可能(尚不)存在。
  • 您可能希望将文本放入框架中以使其更小,而 contentShape 也可能会有所帮助。
  • @chockenberry 正好是一年后。您是否找到了解决问题的有效解决方案,您愿意分享吗?
  • 如果我没有设置allowsHitTesting,如果不透明度≤0.5,SwiftUI 似乎会自动禁用用户交互。
  • 找到答案:stackoverflow.com/a/61225965/11912101 .allowsHitTesting(false)申请UIViewControllerWrapper() 对我有用。

标签: swift swiftui user-interaction


【解决方案1】:

使用 .allowsHitTesting() 怎么样?

https://developer.apple.com/documentation/swiftui/image/3269586-allowshittesting

据我了解,如果它被禁用,它应该将手势传递给后面的视图。

ZStack() {
    ScrollView {
        ...
    }
    Text("Hello.").allowsHitTesting(false)
}

【讨论】:

  • 它对我有用。我在背景视图上有图像,想检测背景上的手势。因此,在图像上添加 allowHitTesting(false) 可以禁止它们干扰手势识别a,并且所有触摸都由背景视图处理。
  • 作为旁注,这最初对我不起作用,因为我添加了一个放置修饰符,但是当我将它移动为最后一个修饰符时,它开始工作了。
  • 这目前不适合我,我在 Map UIViewRepresentable 前面有一个 Circle,如果我拖动 Circle 本身,我无法滚动地图
【解决方案2】:

View 上有一个修饰符来禁用或启用用户交互:

disabled(_ disabled: Bool)

【讨论】:

  • 我尝试将.disabled(true) 放在TextZStack 上,但没有帮助。
  • Apple 文档说:“视图层次结构中的更高视图可以覆盖您在此视图上设置的值。在以下示例中,按钮不是交互式的,因为外部 disabled(_:) 修饰符覆盖内层:HStack { Button(Text("Press")) {} .disabled(false) } .disabled(true)
  • 您是否尝试在其中一个视图上设置 zIndex(1) 以使其向前推进?
  • 在上面看到我自己的答案:看来问题不在于堆栈或其中的视图,而在于 .border() 做了一些意想不到的事情。
【解决方案3】:

您希望确保用某种颜色填充视图,但清除颜色除外(您始终可以更改不透明度)。我还添加了模糊来隐藏元素。这对我有用:

SwiftUI:

ZStack{
    SomeView().blur(radius: 12)
    Rectangle()
        .fill(Color.white.opacity(0))
        .allowsHitTesting(false)
}

另一种禁用用户交互的方法,如滚动或按钮点击,但在用户点击时附加一个操作(例如,向用户发送此功能即将推出或在付费墙后面的消息):

SwiftUI:

VStack{
    SomeView().blur(radius: 12)
}
.contentShape(Rectangle())
.onTapGesture {
    print("No access!")
}

【讨论】:

    【解决方案4】:

    SwiftUI 2.0

     ZStack {
    
        // Your Stack to Disable User Interection
    
    }.disabled(showLoadingIndicator ? true : false)
    

    【讨论】:

      【解决方案5】:

      这很可能是 SwiftUI 中的一个错误,但解决此问题的方法是删除我在 Text 视图中放置的 .border() 以进行边界调试。

      【讨论】:

        【解决方案6】:

        对我来说没什么用,渐变叠加层阻止用户滚动,但他们可以点击。因此,对于.allowsHitTesting(false),我决定制作自己的gradientView 来实现UIViewRepresentable,并在更新函数中执行以下操作。

        func updateUIView(_ uiView: UIView, context: UIViewRepresentableContext<MyCustomGradientView>) {
            uiView.isUserInteractionEnabled = false
            uiView.subviews.forEach({
                $0.isUserInteractionEnabled = false
            })
            // This did the trick
            uiView.superview?.isUserInteractionEnabled = false
        }
        

        【讨论】:

        • 这不是一个完整的答案,请更新它
        【解决方案7】:

        SwiftUI 中的某些元素不能通过 .disabled 或 .allowHitTesting 禁用。一个主要的 HACK 是将元素包装在 TabView 中并对其应用分页样式。同样,这是一个主要的 hack,但它是我目前正在使用的一个有趣的解决方案。

        【讨论】:

          猜你喜欢
          • 2023-03-07
          • 1970-01-01
          • 2012-07-29
          • 2015-06-06
          • 2011-12-14
          • 2013-03-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多