工具栏区域中的 SwiftUI 手势被忽略

SwiftUI gestures in the toolbar area ignored

我想实现一个自定义滑块 SwiftUI 组件并将其放在 SwiftUI Mac 应用程序的工具栏区域。然而,控件的手势会被忽略,因为系统的 window 移动手势优先。系统 UI 控件不会出现此问题,例如 SliderButton

如何修复下面的代码,使滑块在工具栏区域也能正常工作,而不仅仅是在类似于默认 SwiftUI 组件的 window 内部?

struct MySlider: View {
    @State var offset: CGFloat = 0.0
    var body: some View {
        GeometryReader { gr in
            let thumbSize = gr.size.height
            let maxValue = (gr.size.width - thumbSize) / 2.0
            let gesture = DragGesture(minimumDistance: 0).onChanged { v in
                self.offset = max(min(v.translation.width, maxValue), -maxValue)
            }
            ZStack {
                Capsule()
                Circle()
                    .foregroundColor(Color.yellow)
                    .frame(width: thumbSize, height: thumbSize)
                    .offset(x: offset)
                    .highPriorityGesture(gesture)
            }
        }.frame(width: 100, height: 20)
    }
}
struct ContentView: View {
    @State var value = 0.5
    var body: some View {
        MySlider()
        .toolbar {
            MySlider()
            Slider(value: $value).frame(width: 100, height: 20)
        }.frame(width: 500, height: 100)
    }
}

看起来像是设计限制(或尚未实现的功能 - Apple 未将此类视图视为支持用户交互的项目)。

一种可能的解决方法是将您的活动元素包装成按钮样式。作为容器的按钮被解释为 user-interaction-able 区域,但所有绘图和处理都在您的代码中。

测试 Xcode 13.2 / macOS 12.2

注意:滑块逻辑没有变化

struct MySlider: View {

    var body: some View {
        Button("") {}.buttonStyle(SliderButtonStyle())
    }

    struct SliderButtonStyle: ButtonStyle {
        func makeBody(configuration: Configuration) -> some View {
            MySliderContent()
        }

        struct MySliderContent: View {
            @State var offset: CGFloat = 0.0
            var body: some View {
                GeometryReader { gr in
                    let thumbSize = gr.size.height
                    let maxValue = (gr.size.width - thumbSize) / 2.0
                    let gesture = DragGesture(minimumDistance: 0).onChanged { v in
                        self.offset = max(min(v.translation.width, maxValue), -maxValue)
                    }
                    ZStack {
                        Capsule()
                        Circle()
                            .foregroundColor(Color.yellow)
                            .frame(width: thumbSize, height: thumbSize)
                            .offset(x: offset)
                            .highPriorityGesture(gesture)
                    }
                }.frame(width: 100, height: 20)
            }
        }
    }
}