Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.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 更改窗口标题文本的颜色_Cocoa_Nswindow - Fatal编程技术网

Cocoa 更改窗口标题文本的颜色

Cocoa 更改窗口标题文本的颜色,cocoa,nswindow,Cocoa,Nswindow,我知道这不是一个流行的问题,有些人不喜欢非标准外观的应用程序,但它对我的应用程序很有用 是否可以通过“标准”非私有API方式更改NSWindow标题栏文本的颜色 我知道如果我使用私有API是可能的(但我认为不使用私有API是可能的,因为Pixelmator已经做到了,并且没有被MAS拒绝。我知道也可以通过制作无边界窗口并自己绘制所有内容来实现,但我认为Pixelmator并不是这样做的,因为他们仍然获得标准NSWind附带的所有附加位。)ow标题栏;可拖动图标、重命名窗口、用于文档修订的下拉菜单

我知道这不是一个流行的问题,有些人不喜欢非标准外观的应用程序,但它对我的应用程序很有用

是否可以通过“标准”非私有API方式更改NSWindow标题栏文本的颜色

我知道如果我使用私有API是可能的(但我认为不使用私有API是可能的,因为Pixelmator已经做到了,并且没有被MAS拒绝。我知道也可以通过制作无边界窗口并自己绘制所有内容来实现,但我认为Pixelmator并不是这样做的,因为他们仍然获得标准NSWind附带的所有附加位。)ow标题栏;可拖动图标、重命名窗口、用于文档修订的下拉菜单和全屏按钮

基本上,我使用setBackgroundColor创建了一个黑色窗口:但是文本仍然显示为黑色,这在黑色背景下不起作用


那么,有人知道这样做的方法吗,或者Pixelmator是如何做到的?

您可以使用一些私人API解决问题的评论中提到的问题-但是,您将无法将该应用提交到AppStore

另一个解决方案是获取
[[myWindow contentView]superview]
——这将获得前面提到的
NSThemeView
实例。然后只需搜索视图的子视图(实际上称为框架视图)NSTextField的任何实例的子视图,并修改这些子视图。请注意,这些私有视图的层次结构可能会随着每个OS X版本的变化而变化,这可能会破坏您的代码


最好的解决方案可能是子类化(只有子类,没有其他定制)
NSWindow
,并实现
-title
-setTitle:
方法-对于每个窗口,您可以将实际标题设置为
@”“
(通过调用
[super setTitle:@”“]
)然后将您自己的、以编程方式创建的
NSTextField
实例放入框架视图(即
[[self-contentView]superview]addSubview:myTextField]
,其中
myTextField
是文本字段。您需要确定字段的确切位置等,但这是最简单的部分。

这是Swift中的一个解决方案。时间太晚了,我很累,所以这可能不是最佳方案,但它很有效

首先,这里有一个在层次结构中查找视图的函数,可以选择跳过特定视图。(如果我们要搜索
窗口.contentView.superview.subviews
,并且希望忽略
contentView
中您自己的视图,这将非常有用。)

下面是如何使用它,例如从
NSViewController
子类。请注意,您需要在窗口可见时执行此操作,因此无法在
viewDidLoad
中执行此操作

override func viewDidAppear() {
    if let windowContentView = view.window?.contentView as? NSView {
        if let windowContentSuperView = windowContentView.superview {
            let titleView = findViewInSubview(windowContentSuperView.subviews as [NSView], ignoreView: windowContentView) { (view) -> Bool in
                // We find the title by looking for an NSTextField. You may
                // want to make this test more strict and for example also
                // check for the title string value to be sure.
                return view is NSTextField
            }
            if let titleView = titleView as? NSTextField {
                titleView.attributedStringValue = NSAttributedString(string: "Hello", attributes: [NSForegroundColorAttributeName: NSColor.redColor()])
            }
        }
    }
}

请注意,您正在玩火。像这样的内部构件没有指定是有原因的。

因为OS X 10.10,它应该足以将窗口的外观更改为NSAppearanceNameVibrantDark

  window.appearance = NSAppearance(named:NSAppearanceNameVibrantDark)

我觉得值得一提,因为你能找到的大多数答案都过时了。

我就是这样做的:

#import <objc/runtime.h>

@interface SOWindow : NSWindow
@end

@interface SOWindowFrameOverrides : NSView
@end

@implementation SOWindow

+ (void)load
{
    SEL selector = NSSelectorFromString(@"_currentTitleColor");
    SEL originalSelector = NSSelectorFromString(@"_original_currentTitleColor");
    Class frameClass = NSClassFromString(@"NSThemeFrame");

    Method m = class_getInstanceMethod(frameClass, selector);
    Method m2 = class_getInstanceMethod([SOWindowFrameOverrides class], selector);
    class_addMethod(frameClass, originalSelector, method_getImplementation(m), method_getTypeEncoding(m));
    method_exchangeImplementations(m, m2);
}

@end

@implementation SOWindowFrameOverrides

- (NSColor *)_currentTitleColor
{
    if ([self.window isKindOfClass:[SOWindow class]]) {
        return [NSColor redColor];
    } else {
        return [self _original_currentTitleColor];
    }
}

- (NSColor *)_original_currentTitleColor
{
    // will be filled in at runtime
    return nil;
}

@end
#导入
@界面SOWindow:NSWindow
@结束
@接口SOWindowFrameOverrides:NSView
@结束
@索文多的实施
+(空)荷载
{
SEL selector=NSSelectorFromString(@“_currentTitleColor”);
SEL originalSelector=NSSelectorFromString(@“\u original\u currentTitleColor”);
类frameClass=NSClassFromString(@“NSThemeFrame”);
方法m=class\u getInstanceMethod(框架类,选择器);
方法m2=class_getInstanceMethod([SOWindowFrameOverrides class],选择器);
class_addMethod(frameClass,originalSelector,method_getImplementation(m),method_getTypeEncoding(m));
方法交换实施(m,m2);
}
@结束
@wframeOverrides的实现
-(非彩色*)\u当前标题颜色
{
if([self.window是类的种类:[SOWindow class]]){
返回[NSColor redColor];
}否则{
返回[self\u original\u currentTitleColor];
}
}
-(非彩色*)\u原色\u当前标题颜色
{
//将在运行时填写
返回零;
}
@结束
虽然视图层次结构从Mavericks到Yosemite已经发生了很大的变化,
\u currentTitleColor
已经在API中出现了很长一段时间,并且在不久的将来可能不会改变。即使是艰难的方法swizzling也是一种黑客方式,我发现它比遍历视图层次结构更优雅,但这只是我自己


如果您想进一步自定义标题,可以覆盖
NSThemeFrame
上的
\u titleTextField
以返回自定义文本字段(我已使用它更改项目的背景样式).

我懒得尝试这个,但我想知道如果你得到窗口的内容视图并要求它提供其超级视图,你会得到什么。可能你会得到零,或者你会得到一个包含其他隐藏内容的根视图。你会得到一个名为NSThemeView的私有NSView子类。它确实包含一些关于窗口关闭、最小化和最大化的私有视图mise按钮,但我不知道如何在不使用私有API的情况下访问标题。Matt Gallagher有一篇关于自定义窗口的文章,你应该可以在那里找到一些信息。正如问题中提到的,我不想做自定义窗口,我已经发布了答案。请检查我的This对我有效,但它似乎可以绘制文本twice。第一个文本是正常绘制的,正如所需,但第二个文本有点不对劲。这让它看起来很奇怪。你知道如何解决这个问题吗?这个方法对我很有效。但你仍然需要在设置titleView.attributedStringValue之前设置NSWindow.title,以便标题文本可以正确布局。不使用面板。。。“无法识别的选择器”
\u backstoppedByDefaultAppearance
“NSAppearanceNameVibrantDark看起来不错,但它似乎在我基于OpenGL的应用程序中造成了问题……它似乎创建了半透明的窗口栏,似乎使用了CoreAni
#import <objc/runtime.h>

@interface SOWindow : NSWindow
@end

@interface SOWindowFrameOverrides : NSView
@end

@implementation SOWindow

+ (void)load
{
    SEL selector = NSSelectorFromString(@"_currentTitleColor");
    SEL originalSelector = NSSelectorFromString(@"_original_currentTitleColor");
    Class frameClass = NSClassFromString(@"NSThemeFrame");

    Method m = class_getInstanceMethod(frameClass, selector);
    Method m2 = class_getInstanceMethod([SOWindowFrameOverrides class], selector);
    class_addMethod(frameClass, originalSelector, method_getImplementation(m), method_getTypeEncoding(m));
    method_exchangeImplementations(m, m2);
}

@end

@implementation SOWindowFrameOverrides

- (NSColor *)_currentTitleColor
{
    if ([self.window isKindOfClass:[SOWindow class]]) {
        return [NSColor redColor];
    } else {
        return [self _original_currentTitleColor];
    }
}

- (NSColor *)_original_currentTitleColor
{
    // will be filled in at runtime
    return nil;
}

@end