代码之家  ›  专栏  ›  技术社区  ›  Guig

当窗口处于非活动状态时,带有PlainButtonStyle的按钮不会被点击

  •  0
  • Guig  · 技术社区  · 7 月前

    我正在写一个MacOS应用程序。我正在展示一个按钮。当应用程序处于非活动状态时,如果我单击按钮,按钮的点击事件将在窗口激活的同时触发。到现在为止,一直都还不错。

    但是,如果我现在补充 .buttonStyle(PlainButtonStyle()) 我的按钮是想要的外观,当窗口处于非活动状态时,它不会被点击。第一次点击会激活窗口,我需要第二次点击才能触发按钮。

    Button {
      print("tapped!")
    } label: {
      Image(systemName: "doc.on.doc")
        .resizable()
        .frame(width: 14, height: 14)
        .padding(5)
    }
    .buttonStyle(PlainButtonStyle())
    
    1 回复  |  直到 7 月前
        1
  •  1
  •   Sweeper    7 月前

    视图是否可以在不激活其窗口的情况下接收单击事件,由控制 acceptsFirstMouse(for:) 方法当按钮样式为 .plain ,按钮不再由支持 NSButton 谁的 acceptsFirstMouse 方法会返回 true ),所以你不能独自“点击”按钮。

    你可以包装 NSViewRepresentable 围绕按钮,并覆盖 接受第一个鼠标 返回true。

    这是来自的代码 this blog post

    extension SwiftUI.View {
        public func acceptClickThrough() -> some View {
            ClickThroughBackdrop(self)
        }
    }
    
    fileprivate struct ClickThroughBackdrop<Content: SwiftUI.View>: NSViewRepresentable {
        final class Backdrop: NSHostingView<Content> {
            override func acceptsFirstMouse(for event: NSEvent?) -> Bool {
                return true
            }
        }
    
        let content: Content
    
        init(_ content: Content) {
            self.content = content
        }
    
        func makeNSView(context: Context) -> Backdrop {
            let backdrop = Backdrop(rootView: content)
            backdrop.translatesAutoresizingMaskIntoConstraints = false
            return backdrop
        }
    
        func updateNSView(_ nsView: Backdrop, context: Context) {
            nsView.rootView = content
        }
    }
    

    示例用法:

    Button("Foo") {
        print("triggered")
    }
    .buttonStyle(.plain)
    .acceptClickThrough()