NSProgressIndicator无法将背景颜色设置为白色

时间:2016-04-28 21:26:55

标签: swift macos cocoa nsprogressindicator

当我将进度指示器的背景设置为绿色时,它会按预期工作。

代码

loadingIndicator.wantsLayer = true
loadingIndicator.layer?.backgroundColor = NSColor.greenColor().CGColor

结果

enter image description here

但是当我将背景颜色设置为白色时,背景颜色会保持灰色(而不是变为白色)。

代码

loadingIndicator.wantsLayer = true
loadingIndicator.layer?.backgroundColor = NSColor.whiteColor().CGColor

结果

enter image description here

为什么将背景颜色设置为白色不起作用,而绿色呢?我该如何纠正这个问题?我在OS X 10.11.4上。

编辑:这显然只发生在进度指示器位于以弹出窗口显示的视图中时。

4 个答案:

答案 0 :(得分:3)

当我在NSPopover中使用NSProgressIndicator时,我遇到了同样的问题。

我的解决方案是将外观设置为下面的弹出窗口。

popover.appearance = NSAppearance(named: NSAppearanceNameAqua)
  • 尝试使用OSX 10.11.5 / Xcode7.3.1
  • 除NSAppearanceNameVibrantDark之外的任何其他名称也有效

我不确定为什么会这样,但在设置属性后我得到了正确的白色背景颜色。

Screenshot: white background progress inside popover

答案 1 :(得分:2)

我找到了解决这个问题的方法。 NSProgressIndicator的CALayer有一个子图层,显示您正在看到的有色背景颜色。隐藏该子图层将导致无法显示任何背景,并保持微调器可见。

CALayer *layer = [[self popoverProgressIndicator] layer];
CALayer *backgroundLayer = [[layer sublayers] firstObject];
[backgroundLayer setHidden:YES];

我在使用解决方案here更改背景的NSPopover内部时才看到此问题。

答案 2 :(得分:2)

我最近也遇到了这个问题,但是我的问题与macOS 10.14中的暗模式/亮模式有关。就像其他人提到的那样,在NSPopover中使用NSProgressIndicator似乎也发生了,而且在Safari App Extension弹出框内使用时(我认为这是因为Safari弹出框也是您不能直接访问的NSPopover)。如horimislime所述,弄乱外观似乎可以解决问题。

我创建了一个NSProgressIndicator子类,仅当应用程序在macOS 10.14或更高版本中运行时,该子类才会自动将其自身外观设置为系统具有的外观,即使在应用程序运行时这种外观发生了变化。进度指示器在以前的OS版本中对我有效,因此如果系统小于10.14,则我将其保持不变。

代码如下:

import Cocoa

class TransparentProgressIndicator: NSProgressIndicator {

    override func awakeFromNib() {
        super.awakeFromNib()

        if #available(OSX 10.14, *) {
            // register an observer to detect when the system appearance changes
            UserDefaults.standard.addObserver(self, forKeyPath: "AppleInterfaceStyle", options: .new, context: nil)

            // set the starting appearance to the one the system has
            let light = NSAppearance(named: .aqua)
            let dark = NSAppearance(named: .darkAqua)
            self.appearance = UserDefaults.standard.string(forKey: "AppleInterfaceStyle") == "Dark" ? dark : light
        }
    }

    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {

        if #available(OSX 10.14, *) {
            if keyPath == "AppleInterfaceStyle" {

                // set the current appearance to the one the system has
                let val: String? = change?[NSKeyValueChangeKey.newKey] as? String

                if (val == "Dark") {
                    self.appearance = NSAppearance(named: .darkAqua)
                }
                else {
                    self.appearance = NSAppearance(named: .aqua)
                }
            }
        }
    }

    deinit {
        if #available(OSX 10.14, *) {
            UserDefaults.standard.removeObserver(self, forKeyPath: "AppleInterfaceStyle")
        }
    }

}

这样,进度指示器将保持透明,没有奇怪的背景色,并且仍会根据系统外观更改其配色方案。 为了使用它,您需要在接口构建器中将该子类的名称添加为“自定义类”属性:

Custom Class example

现在,为了按照问题中的要求自定义背景色,您可以只包含一个NSBox并为其添加颜色:

Custom NSBox properties ProgressIndicator constraints

答案 3 :(得分:1)

NSProgressIndicator中使用NSPopover时,我遇到了同样的问题。

我的解决方案是将外观设置为NSProgressIndicator,如下所示。

@IBOutlet weak var progressIndicator: NSProgressIndicator!

override func viewDidLoad() {
    super.viewDidLoad()
    self.progressIndicator.appearance = NSAppearance(named: .aqua)
}

如果您愿意,甚至可以将外观设置为整个弹出框,就可以解决问题:

popover.appearance = NSAppearance(named: .aqua)