NSTextView的定位检查器栏

Cha*_*ltz 4 xcode cocoa objective-c

为文本视图启用“检查器栏”很容易,以便带有各种格式按钮的栏出现在屏幕顶部。(尽管直到我学会确定要在滚动视图中选择文本视图而不是滚动视图本身之前,我还是有些困惑。)我可以以编程方式使用[textView setUsesInspectorBar:YES]或转到“属性”检查器,然后在“使用”部分中选中“检查器栏”框。

我的问题是,如何进一步控制检查栏?我在XCode文档或在线中找不到有关它的信息时遇到麻烦。我希望能够将其放置在屏幕上的其他位置。能够选择栏中的特定控件也很不错。

Jos*_* E. 6

虽然已经晚了四年,但我觉得互联网上的某个人将来可能会从中受益。我花了太长时间试图弄清楚这一点。

正如其他人指出的那样,检查器栏类似乎是一个私有类(__NSInspectorBarView)。因此,可能不建议修改。

尽管如此!好奇的人必须知道。在这篇文章发表时(2016 年 4 月),检查器栏已插入窗口的附件栏。NSWindow从 OS X 10.10 开始,您可以使用调用中的数组属性获取附件视图的列表titlebarAccessoryViewControllers[]

这里有一些 Swift 2.0 代码可以做到这一点,假设您没有事先将任何其他附件视图插入到窗口中

if window.titlebarAccessoryViewControllers.count > 0 {
        let textViewInspectorBar = self.titlebarAccessoryViewControllers[0].view
        let inspectorBarHeight: CGFloat = textViewInspectorBar!.frame.height // 26.0 pt
    }
Run Code Online (Sandbox Code Playgroud)

值得注意的是,在全屏模式应用程序中,附件视图的处理方式有所不同https://developer.apple.com/library/mac/documentation/General/Conceptual/MOSXAppProgrammingGuide/FullScreenApp/FullScreenApp.html

我个人不会尝试移动附件视图,因为它们是设计用于保留在工具栏中的特殊视图(如果我完全理解我所读的内容)。

NSTitlebarAccessoryViewController 参考: https://developer.apple.com/library/mac/documentation/AppKit/Reference/NSTitlebarAccessoryViewController_Class/

  • 为其他程序员提供有用的信息永远不会太晚!:) (2认同)

Ver*_*ous 5

答案是,您无意进一步控制检查器栏。该文档中没有任何内容,因为没有任何内容。苹果公司所说,使用它或不使用它。

但是,如果深入研究它,您会发现检查器栏是一个非常有趣的控件。它不会显示为文本视图的一部分,而是(私下)嵌入在“窗口视图”本身中。当我说“窗口视图”时,是指内容视图的超级视图。

如果列出该“窗口视图”的子视图:

NSLog(@"%@", [self.testTextView.window.contentView superview].subviews);
Run Code Online (Sandbox Code Playgroud)

您最终得到:

2012-08-02 15:59:30.145 Example[16702:303] (
    "<_NSThemeCloseWidget: 0x100523dc0>", // the close button
    "<_NSThemeWidget: 0x100525ce0>", // the minimize button?
    "<_NSThemeWidget: 0x100524e90>", // the maximize button?
    "<NSView: 0x100512ad0>", // the content view
    "<__NSInspectorBarView: 0x100529d50>", // the inspector view
    "(<NSToolbarView: 0x10054e650>: FD2E0533-AB18-4E7E-905A-AC816CB80A26)" // the toolbar
)
Run Code Online (Sandbox Code Playgroud)

如您所见,AppKit将检查器栏与其他顶级窗口控件置于同一级别。现在,这已经进入了私有API领域,但只要修改“窗口视图”,就不应拒绝任何应用程序。


您可以尝试__NSInspectorBarView从此处获取对的引用。似乎始终是内容视图之后的子视图,因此类似的事情可能会起作用:

NSArray *topLevelViews = [self.testTextView.window.contentView superview].subviews;
NSUInteger indexOfContentView = [topLevelViews indexOfObject:self.testTextView.window.contentView];
if (indexOfContentView + 1 < topLevelViews.count) {
    NSView *inspectorBar = [topLevelViews objectAtIndex:indexOfContentView + 1];
    NSLog(@"%@", inspectorBar);
}
NSLog(@"%@", topLevelViews);
Run Code Online (Sandbox Code Playgroud)

如果Apple更改顶级视图的顺序,这会立即中断,所以对于生产应用程序来说,这可能不是一个好主意。另一个想法是:

NSView *inspectorBarView = nil;
for (NSView *topLevelView in topLevelViews) {
    if ([topLevelView isKindOfClass:NSClassFromString(@"__NSInspectorBarView")]) {
        inspectorBarView = topLevelView;
    }
}
NSLog(@"%@", inspectorBarView);
Run Code Online (Sandbox Code Playgroud)

我不知道的使用是否NSClassFromString()会通过App Store审查指南,但是,由于它又一次依赖于私有API,因此我不知道。


话虽如此,一旦您获得对检查器条形视图的引用,事情仍然无法很好地进行。您可以尝试将其重新定位在底部:

if (inspectorBarView) {
    NSRect newFrame = inspectorBarView.frame;
    newFrame.origin = NSZeroPoint;
    [inspectorBarView setAutoresizingMask:NSViewMaxYMargin | NSViewMaxXMargin];
    [inspectorBarView setFrame:newFrame];
}
Run Code Online (Sandbox Code Playgroud)

但是您最终会使用错误绘制的工具栏,因此在那里需要做更多的工作:

在此处输入图片说明

我的想法是尝试将内容视图的高度向上移动以覆盖灰色的剩余区域(每次更改窗口大小时都必须这样做,也许对自动调整大小的蒙版进行修补可能会更容易),并自定义绘制底部检查器栏的背景。

编辑

哦,您也应该为此提交功能请求。bugreport.apple.com