swift - 允许用户在 macCatalyst 中自定义 Touch Bar

标签 swift macos mac-catalyst nstouchbar

在 Catalyst Swift 项目中,UIViewController 子类创建一个 TouchBar,如下所示:

override func makeTouchBar() -> NSTouchBar? {
    let touchBar = NSTouchBar()
    touchBar.delegate = self
    touchBar.defaultItemIdentifiers = [<<some>>]
    touchBar.customizationAllowedItemIdentifiers = [<<more>>]
    touchBar.customizationIdentifier = "com.me.myapp.touchbar"
    return touchBar
}

默认项目显示在 TouchBar 上,但没有菜单项可自定义它们。 读取 the TouchBar documentation 有两种选择:

1:NSApplication

The Customization Menu Item A user invokes the customization UI for a particular NSTouchBar object, when it is visible in the Touch Bar, by choosing the bar customization menu item. To enable this menu item you must explicitly opt-in, which you can do in the following ways:

  • If you want the system to automatically name, place, validate, and activate this menu item in your app’s menus, set the isAutomaticCustomizeTouchBarMenuItemEnabled property of your app object (of type NSApplication) to true.
  • To explicitly place the customization menu item in one of your app’s menus, employ the toggleTouchBarCustomizationPalette(_:) method of your app object. When you do this, the system still names and validates the menu item, and hides it on systems that do not have a Touch Bar.

尝试执行其中任一操作都会产生 'NSApplication' 在 Mac Catalyst 中不可用 错误。 因此,经过一番谷歌搜索后,我发现了这个:

NSClassFromString("NSApplication")?.setValue(true, forKeyPath: "sharedApplication.automaticCustomizeTouchBarMenuItemEnabled")
print(NSClassFromString("NSApplication")?.value(forKeyPath: "sharedApplication.isAutomaticCustomizeTouchBarMenuItemEnabled"))

编译并执行得很好。它甚至打印出之前有 Optional(0)Optional(1) 。但菜单项仍然不存在。我在生成 TouchBar、生成​​菜单和 func application(_, didFinishLaunchingWithOptions) 时尝试过此操作,但无济于事。

我无法让第二个不给我错误。

2:触摸栏

奇怪的是 NSTouchBar 有 the same property ,但正在运行

NSTouchBar.isAutomaticCustomizeTouchBarMenuItemEnabled = true

在任何时候(也可以编译)不会产生任何差异。

问题

这是一个缺失的功能还是有办法实现它。如果是这样:怎么办?

编辑

我正在自定义菜单栏。由于错误,为两个选项设置相同的快捷方式会导致 Xcode 中出现以下输出:

2020-02-15 14:08:01.492510+0100 Myapp[71888:2189305] [MenuBuilder] Menu has duplicates --
<_UIImmutableKeyCommand: 0x60000374e700> -> Title: Toggle Center Column  Action: executeOptionForKeyCommand:  Input: 1 + (UIKeyModifierCommand)
<_UIImmutableKeyCommand: 0x60000374e640> -> Title: Toggle Left Column  Action: executeOptionForKeyCommand:  Input: 1 + (UIKeyModifierCommand)
Make a symbolic breakpoint at _UIMenuBuilderError to catch this in the debugger.
2020-02-15 14:08:01.492701+0100 Myapp[71888:2189305] *** Assertion failure in -[_UIMenuBuilder _insertMenu:intoParentMenu:newParentMenu:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKitCore/UIKit-3901.4.905/UIMenu/UIMenuBuilder.m:456
2020-02-15 14:08:01.492950+0100 Myapp[71888:2189305] [General] inserted menu has duplicate submenu, command or key command, or a key command is missing input or action
2020-02-15 14:08:01.497025+0100 Myapp[71888:2189305] [General] (
    0   CoreFoundation                      0x00007fff2f3858ab __exceptionPreprocess + 250
    1   libobjc.A.dylib                     0x00007fff6563f805 objc_exception_throw + 48
    2   CoreFoundation                      0x00007fff2f3aed10 +[NSException raise:format:arguments:] + 88
    3   Foundation                          0x00007fff31aa7241 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 191
    4   UIKitCore                           0x00007fff6d31dded -[_UIMenuBuilder _insertMenu:intoParentMenu:newParentMenu:] + 1426
    5   UIKitCore                           0x00007fff6d31e9ef -[_UIMenuBuilder insertChildMenu:atStartOfMenuForIdentifier:] + 177
    6   Myapp                               0x000000010010a87b $s5Myapp11AppDelegateC9buildMenu4withySo13UIMenuBuilder_p_tF + 4987
    7   Myapp                               0x000000010010b150 $s5Myapp11AppDelegateC9buildMenu4withySo13UIMenuBuilder_p_tFTo + 64
    8   UIKitCore                           0x00007fff6d31c428 -[UIResponder _buildMenuFromChainWithBuilder:] + 115
    9   UIKitCore                           0x00007fff6d31c17f -[UIMenuSystem _newBuilderFromResponderChain:] + 72
    10  UIKitCore                           0x00007fff6d31c114 -[UIMenuSystem _automaticallyRebuildIfNeeded] + 88
    11  UIKitCore                           0x00007fff6d31c09e -[UIMenuSystem _rootMenu] + 27
    12  UIKitCore                           0x00007fff6d3144d9 -[_UIMenuBarController _rebuildRootCommandGroup] + 66
    13  Foundation                          0x00007fff3197ffab -[__NSObserver _doit:] + 296
    14  CoreFoundation                      0x00007fff2f2ff35f __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 12
    15  CoreFoundation                      0x00007fff2f2ff2f3 ___CFXRegistrationPost1_block_invoke + 63
    16  CoreFoundation                      0x00007fff2f2ff268 _CFXRegistrationPost1 + 372
    17  CoreFoundation                      0x00007fff2f2feebe ___CFXNotificationPost_block_invoke + 97
    18  CoreFoundation                      0x00007fff2f2ce7e2 -[_CFXNotificationRegistrar find:object:observer:enumerator:] + 1575
    19  CoreFoundation                      0x00007fff2f2cdc82 _CFXNotificationPost + 1351
    20  Foundation                          0x00007fff319e6048 postQueueNotifications + 718
    21  CoreFoundation                      0x00007fff2f3090ee __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
    22  CoreFoundation                      0x00007fff2f309014 __CFRunLoopDoObservers + 457
    23  CoreFoundation                      0x00007fff2f308832 __CFRunLoopRun + 1514
    24  CoreFoundation                      0x00007fff2f307bd3 CFRunLoopRunSpecific + 499
    25  HIToolbox                           0x00007fff2de5d65d RunCurrentEventLoopInMode + 292
    26  HIToolbox                           0x00007fff2de5d39d ReceiveNextEventCommon + 600
    27  HIToolbox                           0x00007fff2de5d127 _BlockUntilNextEventMatchingListInModeWithFilter + 64
    28  AppKit                              0x00007fff2c4cdba4 _DPSNextEvent + 990
    29  AppKit                              0x00007fff2c4cc380 -[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 1352
    30  AppKit                              0x00007fff2c4be09e -[NSApplication run] + 658
    31  AppKit                              0x00007fff2c490465 NSApplicationMain + 777
    32  AppKit                              0x00007fff2c7b369c _NSApplicationMainWithInfoDictionary + 16
    33  UIKitMacHelper                      0x00007fff602de8f1 UINSApplicationMain + 322
    34  UIKitCore                           0x00007fff6d186273 UIApplicationMain + 2105
    35  Myapp                               0x000000010010b39b main + 75
    36  libdyld.dylib                       0x00007fff669ad7fd start + 1
)
2020-02-15 14:08:27.979587+0100 Myapp[71888:2189305] [Layout] Unable to simultaneously satisfy constraints:
(
    "<NSAutoresizingMaskLayoutConstraint:0x600002183ac0 h=-&- v=-&- _SC_RESULTS_TABLE.minY == 0   (active, names: _SC_RESULTS_TABLE:0x100dc3140, '|':SCTMenuView:0x100dca2e0 )>",
    "<NSAutoresizingMaskLayoutConstraint:0x600002183f70 h=-&- v=-&- V:|-(202)-[_SC_RESULTS_TABLE]   (active, names: _SC_RESULTS_TABLE:0x100dc3140, '|':SCTMenuView:0x100dca2e0 )>",
    "<NSAutoresizingMaskLayoutConstraint:0x60000217f200 h=--& v=--& SCTMenuView:0x100dca2e0.height == 59   (active)>"
)

Will attempt to recover by breaking constraint 
<NSAutoresizingMaskLayoutConstraint:0x600002183f70 h=-&- v=-&- V:|-(202)-[_SC_RESULTS_TABLE]   (active, names: _SC_RESULTS_TABLE:0x100dc3140, '|':SCTMenuView:0x100dca2e0 )>

Set the NSUserDefault NSConstraintBasedLayoutVisualizeMutuallyExclusiveConstraints to YES to have -[NSWindow visualizeConstraints:] automatically called when this happens.  And/or, set a symbolic breakpoint on LAYOUT_CONSTRAINTS_NOT_SATISFIABLE to catch this in the debugger.
2020-02-15 14:08:29.504823+0100 Myapp[71888:2189305] [MenuBuilder] Menu has duplicates --
<_UIImmutableKeyCommand: 0x60000375e400> -> Title: Toggle Center Column  Action: executeOptionForKeyCommand:  Input: 1 + (UIKeyModifierCommand)
<_UIImmutableKeyCommand: 0x60000375e340> -> Title: Toggle Left Column  Action: executeOptionForKeyCommand:  Input: 1 + (UIKeyModifierCommand)
Make a symbolic breakpoint at _UIMenuBuilderError to catch this in the debugger.
2020-02-15 14:08:29.504936+0100 Myapp[71888:2189305] *** Assertion failure in -[_UIMenuBuilder _insertMenu:intoParentMenu:newParentMenu:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKitCore/UIKit-3901.4.905/UIMenu/UIMenuBuilder.m:456
2020-02-15 14:08:29.506015+0100 Myapp[71888:2189305] [General] inserted menu has duplicate submenu, command or key command, or a key command is missing input or action
2020-02-15 14:08:29.514279+0100 Myapp[71888:2189305] [General] (
    0   CoreFoundation                      0x00007fff2f3858ab __exceptionPreprocess + 250
    1   libobjc.A.dylib                     0x00007fff6563f805 objc_exception_throw + 48
    2   CoreFoundation                      0x00007fff2f3aed10 +[NSException raise:format:arguments:] + 88
    3   Foundation                          0x00007fff31aa7241 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 191
    4   UIKitCore                           0x00007fff6d31dded -[_UIMenuBuilder _insertMenu:intoParentMenu:newParentMenu:] + 1426
    5   UIKitCore                           0x00007fff6d31e9ef -[_UIMenuBuilder insertChildMenu:atStartOfMenuForIdentifier:] + 177
    6   Myapp                               0x000000010010a87b $s5Myapp11AppDelegateC9buildMenu4withySo13UIMenuBuilder_p_tF + 4987
    7   Myapp                               0x000000010010b150 $s5Myapp11AppDelegateC9buildMenu4withySo13UIMenuBuilder_p_tFTo + 64
    8   UIKitCore                           0x00007fff6d31c428 -[UIResponder _buildMenuFromChainWithBuilder:] + 115
    9   UIKitCore                           0x00007fff6d31c17f -[UIMenuSystem _newBuilderFromResponderChain:] + 72
    10  UIKitCore                           0x00007fff6d31c114 -[UIMenuSystem _automaticallyRebuildIfNeeded] + 88
    11  UIKitCore                           0x00007fff6d3cf5aa -[UIMenuSystem _keyCommands] + 27
    12  UIKitCore                           0x00007fff6d3cf375 -[UIApplication _keyCommands] + 105
    13  UIKitCore                           0x00007fff6dd17069 -[UIResponder _keyCommandForEvent:target:] + 182
    14  UIKitCore                           0x00007fff6dd17405 -[UIResponder _keyCommandForEvent:target:] + 1106
    15  UIKitCore                           0x00007fff6dd17405 -[UIResponder _keyCommandForEvent:target:] + 1106
    16  UIKitCore                           0x00007fff6dd17405 -[UIResponder _keyCommandForEvent:target:] + 1106
    17  UIKitCore                           0x00007fff6dd17405 -[UIResponder _keyCommandForEvent:target:] + 1106
    18  UIKitCore                           0x00007fff6dd17405 -[UIResponder _keyCommandForEvent:target:] + 1106
    19  UIKitCore                           0x00007fff6e0a36ce -[UIApplication(iOSMacSupport) _physicalKeyEvent:unmodified:shiftModified:commandModified:modifierFlags:isDown:timestampMachAbs:] + 517
    20  UIKitCore                           0x00007fff6e0a3803 -[UIApplication(iOSMacSupport) _sendKeyEvent:unmodified:shiftModified:commandModified:modifierFlags:isDown:timestampMachAbs:] + 116
    21  UIKitCore                           0x00007fff6e0a1c38 __58-[UIApplication(iOSMacSupport) _initiateIOSMacConnections]_block_invoke_3.396 + 124
    22  UIKitMacHelper                      0x00007fff602f4e3c -[UINSInputView _sendKeyEvent:isDown:] + 452
    23  UIKitMacHelper                      0x00007fff602f4ebd -[UINSInputView keyUp:] + 47
    24  AppKit                              0x00007fff2c675b98 -[NSWindow(NSEventRouting) _reallySendEvent:isDelayedEvent:] + 6512
    25  AppKit                              0x00007fff2c674005 -[NSWindow(NSEventRouting) sendEvent:] + 349
    26  AppKit                              0x00007fff2c672ccf -[NSApplication(NSEvent) sendEvent:] + 2739
    27  AppKit                              0x00007fff2c4be0cf -[NSApplication run] + 707
    28  AppKit                              0x00007fff2c490465 NSApplicationMain + 777
    29  AppKit                              0x00007fff2c7b369c _NSApplicationMainWithInfoDictionary + 16
    30  UIKitMacHelper                      0x00007fff602de8f1 UINSApplicationMain + 322
    31  UIKitCore                           0x00007fff6d186273 UIApplicationMain + 2105
    32  Myapp                               0x000000010010b39b main + 75
    33  libdyld.dylib                       0x00007fff669ad7fd start + 1
)
2020-02-15 14:08:30.338067+0100 Myapp[71888:2189305] *** Assertion failure in -[NSApplication _commonBeginModalSessionForWindow:relativeToWindow:modalDelegate:didEndSelector:contextInfo:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/AppKit/AppKit-1894.30.142/AppKit.subproj/NSApplication.m:3694
2020-02-15 14:08:30.338318+0100 Myapp[71888:2189305] [General] Modal session requires modal window
2020-02-15 14:08:30.348833+0100 Myapp[71888:2189305] [General] (
    0   CoreFoundation                      0x00007fff2f3858ab __exceptionPreprocess + 250
    1   libobjc.A.dylib                     0x00007fff6563f805 objc_exception_throw + 48
    2   CoreFoundation                      0x00007fff2f3aed10 +[NSException raise:format:arguments:] + 88
    3   Foundation                          0x00007fff31aa7241 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 191
    4   AppKit                              0x00007fff2c7cf9d0 -[NSApplication _commonBeginModalSessionForWindow:relativeToWindow:modalDelegate:didEndSelector:contextInfo:] + 1583
    5   AppKit                              0x00007fff2c7cf39b -[NSApplication beginModalSessionForWindow:] + 37
    6   AppKit                              0x00007fff2c7cf2fc __35-[NSApplication runModalForWindow:]_block_invoke_2 + 39
    7   AppKit                              0x00007fff2c7cf2c2 __35-[NSApplication runModalForWindow:]_block_invoke + 70
    8   AppKit                              0x00007fff2c7ceb4c _NSTryRunModal + 100
    9   AppKit                              0x00007fff2c7cea31 -[NSApplication runModalForWindow:] + 128
    10  AppKit                              0x00007fff2cd21be6 __82-[NSTouchBarCustomizationController toggleCustomizationPalette:forceControlStrip:]_block_invoke_4 + 148
    11  AppKit                              0x00007fff2cd244c7 ___NSRunLoopTimerCreateWithHandler_block_invoke + 34
    12  CoreFoundation                      0x00007fff2f324804 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 20
    13  CoreFoundation                      0x00007fff2f3243be __CFRunLoopDoTimer + 859
    14  CoreFoundation                      0x00007fff2f323e9e __CFRunLoopDoTimers + 317
    15  CoreFoundation                      0x00007fff2f308aed __CFRunLoopRun + 2213
    16  CoreFoundation                      0x00007fff2f307bd3 CFRunLoopRunSpecific + 499
    17  HIToolbox                           0x00007fff2de5d65d RunCurrentEventLoopInMode + 292
    18  HIToolbox                           0x00007fff2de5d2a9 ReceiveNextEventCommon + 356
    19  HIToolbox                           0x00007fff2de5d127 _BlockUntilNextEventMatchingListInModeWithFilter + 64
    20  AppKit                              0x00007fff2c4cdba4 _DPSNextEvent + 990
    21  AppKit                              0x00007fff2c4cc380 -[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 1352
    22  AppKit                              0x00007fff2c4be09e -[NSApplication run] + 658
    23  AppKit                              0x00007fff2c490465 NSApplicationMain + 777
    24  AppKit                              0x00007fff2c7b369c _NSApplicationMainWithInfoDictionary + 16
    25  UIKitMacHelper                      0x00007fff602de8f1 UINSApplicationMain + 322
    26  UIKitCore                           0x00007fff6d186273 UIApplicationMain + 2105
    27  Myapp                               0x000000010010b39b main + 75
    28  libdyld.dylib                       0x00007fff669ad7fd start + 1
)
2020-02-15 14:08:31.815095+0100 Myapp[71888:2189305] [AXRuntimeCommon] Unknown client: Myapp

但是自定义 TouchBar 操作会显示在菜单中(我所有的自定义操作都消失了),❗MISSING LABEL❗ 问题很容易解决。

所以我想知道是否是我的菜单自定义代码导致了错误,但是在我的 AppDelegate 中取消注释整个 override func buildMenu(with builder: UIMenuBuilder) 不会导致自定义菜单出现 - 只是快捷方式冲突确实如此。

image

最佳答案

在我的 Swift Catalyst 应用程序(macOS 10.15.3、Xcode 11.3.1)中,我可以调用

NSTouchBar.isAutomaticCustomizeTouchBarMenuItemEnabled = true

在我的重写 func makeTouchBar() 方法中,“自定义触摸栏...”菜单项出现在“查看”菜单选项卡中。对于丢失的标签,可以执行以下操作:

func touchBar(_ touchBar: NSTouchBar, makeItemForIdentifier identifier: NSTouchBarItem.Identifier) -> NSTouchBarItem? {
        if identifier == yourIdentifier {
            let item = NSPickerTouchBarItem(...)

            item.customizationLabel = "View Segmented Control"

            return item
        }
        return nil
    }

关于swift - 允许用户在 macCatalyst 中自定义 Touch Bar,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60228454/

相关文章:

ios - iOS 应用程序的 Citrix MDX 工具包打包失败并出现 "Mach Header contains Invalid Flag bits ..."错误

Java无法以正确的编码读取汉字

swift - Mac 催化剂 : tableView allowmultipleselection not working

swift - 如何禁用 MacCatalyst 上的全屏按钮

ios - 如何快速将静态单元格拖入 tableView?

ios - 通过更改 alpha swift iOS 启用用户交互

arrays - 创建数组

macos - 向 Beta 测试人员分发沙盒 Mac 应用程序的最佳方式

macos - 在 macOS 上运行 docker X11 应用程序

ios - 为什么 Mac Catalyst 应用程序不使用 numberOfTouchesRequired?