NSOutlineView
是NSTableView
的子类。目前,NSTableView
支持两种实现。
要制作OSX 10.8 Finder样式侧栏(带有自动灰色图标样式),需要使用带有源列表高亮样式的基于视图的表格视图。
使用NIB,这是典型的工作。没什么难的。 (参见SidebarDemo)但我想避免使用任何NIB或Interface Builder。我想纯粹以编程方式制作侧栏。
在这种情况下,我有很大的问题。 AFAIK,没有办法为特定细胞提供原型视图。当我打开.xib
文件时,我看到<tableColumn>
包含<prototypeCellViews>
。这指定了将用于列的视图。我找不到如何使用公共API以编程方式设置它。
作为一种解决方法,我尝试使用-[NSTableView makeViewWithIdentifier:owner:]
和-[NSTableView viewAtColumn:row:makeIfNecessary:]
手动创建单元格,但它们都不会返回视图实例。我创建了一个NSTableCellView
,但它没有图像视图和文本字段实例。我也尝试设置它们,但字段标记为assign
,因此实例立即解除分配。我试图通过强行保留它来保持它,但它不起作用。 NSTableView
不管理它们,所以我确信表格视图不喜欢我的实现。
我相信有一个属性可以为列设置此原型视图。但我找不到他们。我在哪里可以找到该属性并以编程方式使用source-list样式制作系统默认的NSOutlineView
?
答案 0 :(得分:4)
如果您按照SidebarDemo
中的示例操作,他们会使用NSTableCellView
的子类来显示详细信息行。为了模拟 InterfaceBuilder mojo,您可以在构造函数中将所有内容挂钩。其余部分与演示相同(参见outlineView:viewForTableColumn:item:
)。
@interface SCTableCellView : NSTableCellView
@end
@implementation SCTableCellView
- (id)initWithFrame:(NSRect)frameRect {
self = [super initWithFrame:frameRect];
[self setAutoresizingMask:NSViewWidthSizable];
NSImageView* iv = [[NSImageView alloc] initWithFrame:NSMakeRect(0, 6, 16, 16)];
NSTextField* tf = [[NSTextField alloc] initWithFrame:NSMakeRect(21, 6, 200, 14)];
NSButton* btn = [[NSButton alloc] initWithFrame:NSMakeRect(0, 3, 16, 16)];
[iv setImageScaling:NSImageScaleProportionallyUpOrDown];
[iv setImageAlignment:NSImageAlignCenter];
[tf setBordered:NO];
[tf setDrawsBackground:NO];
[[btn cell] setControlSize:NSSmallControlSize];
[[btn cell] setBezelStyle:NSInlineBezelStyle];
[[btn cell] setButtonType:NSMomentaryPushInButton];
[[btn cell] setFont:[NSFont boldSystemFontOfSize:10]];
[[btn cell] setAlignment:NSCenterTextAlignment];
[self setImageView:iv];
[self setTextField:tf];
[self addSubview:iv];
[self addSubview:tf];
[self addSubview:btn];
return self;
}
- (NSButton*)button {
return [[self subviews] objectAtIndex:2];
}
- (void)viewWillDraw {
[super viewWillDraw];
NSButton* btn = [self button];
...
答案 1 :(得分:4)
除了@jeberle 's answer之外,我还需要注意更多内容。
保留文字字段和图片视图的关键是将它们添加为NSTableCellView
的子视图。
将NSTableView.rowSizeStyle
设置为正确的值(非Custom
,这是默认值),以使表格视图自动布局。否则,你必须自己完全布局。
如果您想使用预定义的frame
值,请勿触摸autoresizing
和NSTableViewRowSizeStyle
内容。否则,布局可能会被破坏。
您可以通过提供private func outlineView(outlineView: NSOutlineView, heightOfRowByItem item: AnyObject) -> CGFloat
委托方法来调整行高。设置NSTableView.rowHeight
不是一个好主意,因为它需要NSTableView.rowSizeStyle
设置为Custom
,这将关闭默认提供的单元格文本/图像布局管理。
您可以按设置NSView.identifier
属性重复使用行/单元格视图。 (example)
答案 2 :(得分:1)
这是@jeberle的代码,在Swift 4中(五年后!):
class ProgrammaticTableCellView: NSTableCellView {
override init(frame frameRect: NSRect) {
super.init(frame: frameRect)
self.autoresizingMask = .width
let iv: NSImageView = NSImageView(frame: NSMakeRect(0, 6, 16, 16))
let tf: NSTextField = NSTextField(frame: NSMakeRect(21, 6, 200, 14))
let btn: NSButton = NSButton(frame: NSMakeRect(0, 3, 16, 16))
iv.imageScaling = .scaleProportionallyUpOrDown
iv.imageAlignment = .alignCenter
tf.isBordered = false
tf.drawsBackground = false
btn.cell?.controlSize = .small
// btn.bezelStyle = .inline // Deprecated?
btn.cell?.isBezeled = true // Closest property I can find.
// btn.cell?.setButtonType(.momentaryPushIn) // Deprecated?
btn.setButtonType(.momentaryPushIn)
btn.cell?.font = NSFont.boldSystemFont(ofSize: 10)
btn.cell?.alignment = .center
self.imageView = iv
self.textField = tf
self.addSubview(iv)
self.addSubview(tf)
self.addSubview(btn)
}
required init?(coder decoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
var button: NSButton {
get {
return self.subviews[2] as! NSButton
}
}
}
编辑:我发现了一个链接(不可避免地会消失-它的最新修订于2011年),该链接指向Apple的SidebarDemo,@ jeberle将其代码作为基础。