Macos Mac上的SwiftUI-如何将按钮指定为主按钮?

Macos Mac上的SwiftUI-如何将按钮指定为主按钮?,macos,swiftui,Macos,Swiftui,在AppKit中,我将通过或执行此操作。但是,在SwiftUI中这两种功能似乎都不可能实现,因此如何使按钮成为默认窗口按钮? 目前不可能。我有 但是,现在,您可以包装NSButton 用法: @可用(macOS 10.15,*) 结构ContentView:View{ var body:一些观点{ NativeButton(“提交”,关键字:。返回){ //一些行动 } .padding() } } 实施: //标记:-控件的操作闭包 私有var-controlActionClosurePro

在AppKit中,我将通过或执行此操作。但是,在SwiftUI中这两种功能似乎都不可能实现,因此如何使按钮成为默认窗口按钮?


目前不可能。我有

但是,现在,您可以包装NSButton

用法:

@可用(macOS 10.15,*)
结构ContentView:View{
var body:一些观点{
NativeButton(“提交”,关键字:。返回){
//一些行动
}
.padding()
}
}
实施:

//标记:-控件的操作闭包
私有var-controlActionClosureProtocolAssociatedObjectKey:UInt8=0
协议控制ActionClosureProtocol:NSObjectProtocol{
var目标:AnyObject?{get set}
var操作:选择器?{get set}
}
私人最终类动作蹦床:NSObject{
让行动:(T)->无效
初始化(操作:@escaping(T)->Void){
行动
}
@objc
func操作(发送方:AnyObject){
操作(发送方为!T)
}
}
扩展控制ActionClosureProtocol{
func onAction(uAction:@escaping(Self)->Void){
让蹦床=动作蹦床(动作:动作)
self.target=蹦床
self.action=#选择器(ActionTrampoline.action(发送方:))
objc_setAssociatedObject(self,&controlActionClosureProtocolAssociatedObjectKey,蹦床,.objc_ASSOCIATION_RETAIN)
}
}
扩展NSControl:ControlActionClosureProtocol{}
//标记:-
@可用(macOS 10.15,*)
结构NativeButton:NSViewRepresentable{
枚举键等效项:字符串{
case escape=“\u{1b}”
case`return`=“\r”
}
变量标题:字符串?
var attributedTitle:NSAttributedString?
var密钥等价物:密钥等价物?
让行动:()->无效
初始化(
_标题:字符串,
keyEquivalent:keyEquivalent?=零,
操作:@escaping()->Void
) {
self.title=标题
self.keyEquivalent=keyEquivalent
行动
}
初始化(
_attributedTitle:NSAttributedString,
keyEquivalent:keyEquivalent?=零,
操作:@escaping()->Void
) {
self.attributeditle=attributeditle
self.keyEquivalent=keyEquivalent
行动
}
func MakenView(上下文:NSViewRepresentableContext)->NSButton{
let button=NSButton(标题:,目标:nil,操作:nil)
button.translatesAutoresizingMaskIntoConstraints=false
setContentHuggingPriority(.defaultHigh,用于:。垂直)
setContentHuggingPriority(.defaultHigh,用于:。水平)
返回按钮
}
func updateNSView(unsview:NSButton,context:NSViewRepresentableContext){
如果attributeditle==nil{
nsView.title=标题??“”
}
如果title==nil{
nsView.attributedTitle=attributedTitle??NSAttributedString(字符串:“”)
}
nsView.keyEquivalent=keyEquivalent?.rawValue??“”
nsView.onAction{uu}in
自我行动
}
}
}

这里有一个较短但不太通用的解决方案,用于创建具有返回键等效项和默认按钮蓝色色调的主按钮

struct PrimaryButtonView: NSViewRepresentable {
    typealias NSViewType = PrimaryButton

    let title: String
    let action: () -> Void

    init(_ title: String, action: @escaping () -> Void) {
        self.title = title
        self.action = action
    }

    func makeNSView(context: Context) -> PrimaryButton {
        PrimaryButton(title, action: action)
    }

    func updateNSView(_ nsView: PrimaryButton, context: Context) {
        return
    }
}


class PrimaryButton: NSButton {
    let buttonAction: () -> Void

    init(_ title: String, action: @escaping () -> Void) {
        self.buttonAction = action
        super.init(frame: .zero)
        self.title = title
        self.action = #selector(clickButton(_:))
        bezelStyle = .rounded  //Only this style results in blue tint for button
        isBordered = true
        focusRingType = .none
        keyEquivalent = "\r"
    }

    required init?(coder: NSCoder) {
        fatalError()
    }

    @objc func clickButton(_ sender: PrimaryButton) {
        buttonAction()
    }
}
macOS 11.0/iOS 14: 从Xcode 12 beta开始,Button()上公开了新方法,允许指定keyEquivalent(通过枚举大小写或显式键和修饰符)

设置为默认值:

Button( ... )
    .keyboardShortcut(.defaultAction)
设置为取消:

Button( ... )
    .keyboardShortcut(.cancelAction)

在纯SwiftUI中仍然不可能。希望我们能在今年6月的WWDC上看到这一点。我真的希望如此,很多功能都缺失了,比如搜索栏、这些按钮等等。您的解决方案是否也为按钮着色?我稍后会试试。感谢您的回答。如果您
KeyEquivalent.return
,按钮将突出显示用户的强调色(通常为蓝色)。这是迄今为止Mac的最佳解决方案!很好,自从Xcode 12 beta版以来,在原生SwiftUI中已经有一段时间了。有关详细信息,请参见我的答案。但这仅适用于菜单,而不适用于窗口或工作表内部,因此,即使对于SwiftUI 2,这也不是解决方案。现在在Xcode版本12.2 beta 3(12B5035g)中可以使用,如果您更改按钮样式,Big Sur bêta 11.0(20A5395g)将不起作用。@Andrew这在Popover中可以为我提供非常好的解决方案。该按钮占用了所有可用空间。我怎样才能改变它,这只需要标题的空间?我知道是否有办法使按钮大小与文本一致。我在父视图中显式设置了PrimaryButtonView的框架。