【问题标题】:Adding a subview to an NSStatusBar Item causes 100% CPU将子视图添加到 NSStatusBar 项会导致 100% CPU
【发布时间】:2021-12-28 21:17:32
【问题描述】:

我正在尝试在状态栏项中创建更复杂的控件。我已经设法通过替换 statusBarItem 上的视图来使我的代码正常工作,但这已被弃用并且带有其他一些视觉上的不一致。

我正在尝试向菜单栏上的单个项目添加一行按钮。当我将这些添加为 statusBarItem.button 的子视图时,这会导致 CPU 负载连续增加到 100%。

我已将该问题复制到以下几行代码中,这些代码可以添加到带有 Storyboard 的新 XCode 项目中(编辑 AppDelegate):

var statusBarItem: NSStatusItem?

func applicationDidFinishLaunching(_ aNotification: Notification) {
    //...
    statusBarItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)
    statusBarItem?.button?.title = "Hello World"
    let button = NSButton(title: "Button2", target: self, action: #selector(printYes))
    statusBarItem?.button?.addSubview(button)
    //...
}

启动程序后,CPU 负载将持续保持在 100%。

系统信息:MacOS 11.6.2 XCode 13.2.1

任何帮助或建议将不胜感激,因为我在 Mac UI 编程方面非常缺乏经验。

【问题讨论】:

  • 用按钮覆盖按钮似乎没有意义。尝试将自定义按钮添加到NSView,并将此视图添加到状态项按钮。为什么statusBarItem 是可选的?你可以声明let statusBarItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)
  • 感谢您的回复。在我的原始代码中,这包含在 NSView 中,但无论如何问题仍然存在。我从其他地方复制的。很高兴知道这不是必需的。

标签: swift cocoa


【解决方案1】:

目前,只要尝试将文本作为子视图添加到状态项按钮中,这个问题似乎就存在。

我在我的项目中通过在子视图中呈现带有文本的按钮图像来绕过这个问题。

我如何做到的一个例子(尽管有很多硬编码):

func generateImage(symbol: NSString, active: Bool, visible: Bool) -> NSImage {
    let width = 24
    let height = 16
    let size = CGSize(width: width, height: height)
    let canvas = NSRect(x: 0, y: 0, width: width, height: height)
    let image = NSImage(size: size)
    let imageFill = NSImage(size: size)
    let imageStroke = NSImage(size: size)
    
    let strokeColor = NSColor.black
    if active || visible{
        imageFill.lockFocus()
        strokeColor.setFill()
        NSBezierPath(roundedRect: canvas, xRadius: 6, yRadius: 6).fill()
        imageFill.unlockFocus()
        imageStroke.lockFocus()
        symbol.draw(in: NSRect(x: 9, y: -1, width: 16, height: 16), withAttributes: [.font: NSFont.systemFont(ofSize: 11), .foregroundColor: strokeColor])
        imageStroke.unlockFocus()
        
        image.lockFocus()
        imageFill.draw(in: canvas, from: NSZeroRect, operation: .sourceOut, fraction: 1.0)
        imageStroke.draw(in: canvas, from: NSZeroRect, operation: .destinationOut, fraction: active ? 1.0 : 0.5)
        image.unlockFocus()
    } else {
        image.lockFocus()
        strokeColor.setStroke()
        NSBezierPath(roundedRect: canvas, xRadius: 6, yRadius: 6).stroke()
        symbol.draw(in: NSRect(x: 9, y: -1, width: 16, height: 16), withAttributes: [.font: NSFont.systemFont(ofSize: 11), .foregroundColor: strokeColor])
        image.unlockFocus()

    }
    image.isTemplate = true
    return image
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-23
    • 1970-01-01
    • 2014-08-29
    • 2011-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多