Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Cocoa 如何更改包括三角形部分的NSPopover背景色?_Cocoa - Fatal编程技术网

Cocoa 如何更改包括三角形部分的NSPopover背景色?

Cocoa 如何更改包括三角形部分的NSPopover背景色?,cocoa,Cocoa,如何更改nspoover背景色包括三角形部分 不幸的是,这实际上是不可能的。NSPopover不是为可定制而设计的。如果您想要一个完全定制的外观,最好的选择可能是使用第三方、开源的NSpover替代品,如。我也遇到了同样的问题,但我试图避免将第三方UI元素添加到我的项目中,所以我看得更远。如果您在popover的contentViewController视图中覆盖drawRect:,设置如下颜色: [[NSColor whiteColor] setFill]; NSRectFill([self

如何更改
nspoover
背景色包括三角形部分


不幸的是,这实际上是不可能的。NSPopover不是为可定制而设计的。如果您想要一个完全定制的外观,最好的选择可能是使用第三方、开源的NSpover替代品,如。

我也遇到了同样的问题,但我试图避免将第三方UI元素添加到我的项目中,所以我看得更远。如果您在popover的
contentViewController
视图中覆盖
drawRect:
,设置如下颜色:

[[NSColor whiteColor] setFill];
NSRectFill([self bounds]);
然后你会得到一个白色背景的popover,除了三角形/箭头连接到它相对的矩形。要解决此问题,您必须访问popover的边框视图,该视图恰好包含箭头:

NSView* borderView = [self.view.window valueForKeyPath:@"_borderView"];
我知道,这是一个私人API,但如果你的目标不包括将你的应用提交到应用商店,这是最简单的方法。现在,您也可以覆盖此视图的
drawRect:
。为了避免像使用SDK更新重命名私有的
\u borderView
属性这样的问题,我建议在引用它之前断言borderView是否存在

NSAssert(borderView, @"_borderView does not exist");

它实际上简单得多,并且不需要私有API

使视图控制器的根视图成为自定义类

@implementation MyPopoverRootView

-(void)viewDidMoveToWindow
{
     NSView * aFrameView = [[self.window contentView] superview];
     MyPopoverBackgroundView * aBGView  =[[MyPopoverBackgroundView alloc] initWithFrame:aFrameView.bounds];
     aBGView.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;
     [aFrameView addSubview:aBGView positioned:NSWindowBelow relativeTo:aFrameView];
     [super viewDidMoveToWindow];
}

@end
背景视图只是在其边界中绘制所需的颜色

@implementation MyPopoverBackgroundView

-(void)drawRect:(NSRect)dirtyRect
{
    [[NSColor whiteColor] set];
    NSRectFill(self.bounds);
}

@end

多亏了Stefanf,我才得以工作。下面是查看代码的Swift版本。如前所述,这应该是作为NSPover contentView设置的视图的类

class PopoverContentView:NSView {
    var backgroundView:PopoverBackgroundView?
    override func viewDidMoveToWindow() {
        super.viewDidMoveToWindow()
        if let frameView = self.window?.contentView?.superview {
            if backgroundView == nil {
                backgroundView = PopoverBackgroundView(frame: frameView.bounds)
                backgroundView!.autoresizingMask = NSAutoresizingMaskOptions([.ViewWidthSizable, .ViewHeightSizable]);
                frameView.addSubview(backgroundView!, positioned: NSWindowOrderingMode.Below, relativeTo: frameView)
            }
        }
    }
}



class PopoverBackgroundView:NSView {
    override func drawRect(dirtyRect: NSRect) {
        NSColor.redColor().set()
        NSRectFill(self.bounds)
    }
}

Swift 3

override func viewDidMoveToWindow() {

    guard let frameView = window?.contentView?.superview else {
        return
    }

    let backgroundView = NSView(frame: frameView.bounds)
    backgroundView.wantsLayer = true
    backgroundView.layer?.backgroundColor = .white // colour of your choice
    backgroundView.autoresizingMask = [.viewWidthSizable, .viewHeightSizable]

    frameView.addSubview(backgroundView, positioned: .below, relativeTo: frameView)

}
如果您只想更改popover的背景颜色(包括三角形/箭头),我想您不需要创建NSView的子类。有背景色的图层视图就足够了


另外,您不需要调用super.viewdimovetowindow(),因为它的默认实现不起任何作用。

这是我找到的解决这个问题的最简单方法。无需子类NSView或添加任何子视图

NSView *popoverView = [[[[self popover] contentViewController] view] superview];
[popoverView setWantsLayer:YES];
[[popoverView layer] setBackgroundColor:[[NSColor colorWithWhite:0.8 alpha:1] CGColor]];

获取popover根视图的superview,设置其图层的背景色。

Mike Bedar的解决方案正在发挥作用,但只添加了一件事(为了使三角形填充背景色),即覆盖PopoOverContentView中的draw功能:


Stefanf&Mike Bedar针对Swift 4的解决方案:

  • 转到文件->新建文件->Cocoa类
  • 说出你的班级。PopoverContentView。确保它是NSView的子类
  • 将文件内容设置为:
  • 在情节提要中,选择包含popover内容的视图,然后转到Identity Inspector

  • 将类设置为PopoverContentView


  • 您的府绸及其三角形现在将为绿色。

    很高兴我能帮忙!如果我的答案解决了你的问题,你应该点击左边的复选标记接受它:)可能的重复你可能想接受Stefanf的答案,因为他找到了一个解决方案。这是一个很棒的解决方案!我肯定认为这应该是选择的答案。但是如何更改三角形部分的颜色?MyPopoverRootView是扩展了NSPopover,还是您正在使用它作为PopOver的contentViewController?@MikeBedar这只是一个视图类。没有延伸这不会改变三角形的颜色。这里提到了设置frame属性来解决这个问题,但我不知道需要设置哪个帧以及设置什么。这改变了我的三角形颜色(10.15.5上的测试)现在我如何将我自己的视图分层到这个上面?在
    NSView
    子类中设置这个对我来说很有用。它的代码比公认的答案要少一点(这总是很好的)。谢谢view.wantsLayer=true'是键。谢谢这个代码到哪里去了?在用于
    nspover
    的视图控制器内,这对我在macOS Mojave停止工作。它对你仍然有效吗?
     override func draw(_ dirtyRect: NSRect) {
        backColor.set() // backColor is NSColor
        NSRectFill(self.bounds)
    }
    
    import Cocoa
    
    class PopoverContentView:NSView {
        var backgroundView:PopoverBackgroundView?
        override func viewDidMoveToWindow() {
            super.viewDidMoveToWindow()
            if let frameView = self.window?.contentView?.superview {
                if backgroundView == nil {
                    backgroundView = PopoverBackgroundView(frame: frameView.bounds)
                    backgroundView!.autoresizingMask = NSView.AutoresizingMask([.width, .height]);
                    frameView.addSubview(backgroundView!, positioned: NSWindow.OrderingMode.below, relativeTo: frameView)
                }
            }
        }
    }
    
    class PopoverBackgroundView:NSView {
        override func draw(_ dirtyRect: NSRect) {
            NSColor.green.set()
            self.bounds.fill()
        }
    }