Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
909 views
in Technique[技术] by (71.8m points)

objective c - Positioning inspector bar for NSTextView

It's easy to enable the "inspector bar" for text views so that a bar appears at the top of the screen with various formatting buttons. (Although I had some confusion until I learned to make sure I was selecting the text view in a scroll view, and not the scroll view itself). I can either programmatically use [textView setUsesInspectorBar:YES] or go to the Attributes Inspector and check the "Inspector Bar" box in the "Uses" section.

My question is, how can I further control the inspector bar? I'm having trouble finding information on it in the XCode documentation or online. I'd like to be able to position it in a different place on the screen. Being able to pick and choose which specific controls are in the bar would be great too.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The answer is, you aren't meant to further control the inspector bar. There's nothing in the documentation because, well, there's nothing. Apple's saying, use it or don't use it.

However, if you dig into it a bit, you will find that the inspector bar is a very interesting control. It's not displayed as part of the text view, but rather (privately) embedded in the "window view" itself. When I say "window view," I mean the superview of the content view.

If you list the subviews of that "window view":

NSLog(@"%@", [self.testTextView.window.contentView superview].subviews);

You end up with:

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
)

As you can see, AppKit puts the inspector bar at the same level as other top level window controls. Now this is getting into the land of private APIs, but simply tinkering with the "window view" shouldn't get any apps rejected.


You can try to get a reference to the __NSInspectorBarView from here. It seems like it is always the subview right after the content view, so something like this may work:

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);

Since this immediately breaks if Apple changes the ordering of the top level views, it may not be a good idea for an application for production. Another idea is:

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

I don't know if the use of NSClassFromString() will pass App Store review guidelines, however, since once again, it's dependent on private APIs.


That being said, once you get a reference to the inspector bar view, things still don't work too well. You can try repositioning it at the bottom:

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

But you end up with a misdrawn toolbar, so more work would be necessary there:

enter image description here

My ideas would be to try to shift the content view's height up to cover up the gray left-over area (which would have to be done every time the window is resized, maybe tinkering with autoresizing masks may make it easier) and custom draw a background for the inspector bar at the bottom.

EDIT

Oh, and you should file a feature request for this too. bugreport.apple.com


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...