SwiftUI按钮快捷方式行为怪异

yyhrrdl8  于 2023-11-16  发布在  Swift
关注(0)|答案(1)|浏览(129)

我在我的Macos SwiftUI应用程序项目中有一个MTKView。我试图添加一个按钮和一个快捷键来播放或暂停它。但快捷方式行为奇怪。
产品型号:

class Playable: ObservableObject {
    //data to play
    var playData: PlayData

    var mtkView: MTKView

    @Published isPlaying = false {
        didSet { mtkView.isPaused = !isPlaying }
    }

    func toggle() {
        isPlaying.toggle()
    }
}

class SomethingPlayable: Playable {
    //manage data of playable
}

class SomeOtherThingPlayable: Playable {
    //manage data of playable
}

字符串
SwiftUI查看

Button {
    //play when mtkView is paused, pause when mtkView is playing.
    playable.toggle()
} label: {
    Image(systemName: playable.isPlaying ? "pause" : "play")
}
.keyboardShortcut(.space, modifiers: [])


Playable负责存储MTKView所需的数据和控制MTKView。Playable的子类负责管理数据。如果我点击播放按钮,它会按照我预期的那样工作。但奇怪的是,如果我使用快捷方式,比如按空格键,代码的行为完全不同。更具体地说,如果我使用快捷方式触发播放按钮,在播放按钮的动作中的可播放变量将是一个空的、刚刚初始化的可播放示例,尽管它应该充满由SomethingPlayable或SomethingThingPlayable的示例加载的数据。
如果我像下面这样将playable强制转换为SomethingPlayable或SomethingThingPlayable的示例并调用toggle(),那么当我按空格键时,按钮甚至不会被触发。
SwiftUI查看

Button {
    //play when mtkView is paused, pause when mtkView is playing.
    //playable.toggle()
    if let something = playable as? SomethingPlayable {
        something.toggle()
    } else if let someOtherThing = playable as? SomeOtherThingPlayable {
        someOtherThing.toggle()
    }
} label: {
    Image(systemName: playable.isPlaying ? "pause" : "play")
}
.keyboardShortcut(.space, modifiers: [])


我对Macos应用程序开发非常陌生,并试图熟悉Swift和SwiftUI。我错过了什么吗?
xcode版本:Version 15.0
Swift版本:5
macOS版本:Ventura 13.6

u91tlkcl

u91tlkcl1#

.keyboardShortcut工作得很好。
当我把快捷键改成command+p的时候,keyboardShortcut就可以正常工作了。但是如果快捷键被设置成.space,并且修饰符是空的,keyboardShortcut就会触发一些我仍然无法跟踪的东西。这是另一个问题。当我弄清楚的时候,我会更新这个答案。
谢谢.
更新:我试着跟踪播放按钮所在的视图的更新。2下面是我所做的。

struct PlayerCtlView: View {
    @ObservedObject var playable: TSPlayable
    private var uuid = UUID()

    init(playable: TSPlayable) {
        self.playable = playable
        printUUID()
    }

    private func printUUID() {
        print("PlayerCtlView.uuid = \(uuid)")
    }

    var body: some View {
        Button {
            //play when mtkView is paused, pause when mtkView is playing.
            printUUID()
            playable.toggle()
        } label: {
            Image(systemName: playable.isPlaying ? "pause" : "play")
        }
        .keyboardShortcut(.space, modifiers: [])
    }
}

字符串
我在视图中添加了一个uuid属性,每当PlayerCtlView被初始化时,它都会被设置一个新的值并打印出来。当播放按钮被触发时,也会打印这个uuid。然后,我发现了一个有趣的事情。每当我按空格键触发播放按钮时,UUID将是相同的。2在PlayerCtlView第一次初始化时设置的那个。3并且视图将像它第一次被初始化一样工作。虽然PlayerCtlView已经更新了好几次,uuid也改变了好几次。而且不管PlayerCtlView最近一次更新时uuid是怎么设置的。如果我把快捷键改为其他的东西,比如command+P,它都可以正常工作。
显然,SwiftUI会拦截一些键盘输入,比如空格键和Tab键,并在响应用户输入之前悄悄地做一些事情。调查这种现象远远超出了我的能力范围。所以我暂时把这个问题放在一边。

相关问题