我正在尝试在基于视图的NSOutlineView中自定义公开箭头外观。我看到建议使用
- (void)outlineView:(NSOutlineView *)outlineView willDisplayOutlineCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item
委托方法来实现它。问题是由于某种原因没有调用此方法。我有2个自定义单元格视图 - 一个用于项目,第二个用于标题项目。可能是这个方法没有调用基于视图的大纲视图?狮子座可能会被打破?
请说清楚。
答案 0 :(得分:31)
子类NSOutlineView并覆盖makeViewWithIdentifier:owner:
- (id)makeViewWithIdentifier:(NSString *)identifier owner:(id)owner {
id view = [super makeViewWithIdentifier:identifier owner:owner];
if ([identifier isEqualToString:NSOutlineViewDisclosureButtonKey]) {
// Do your customization
}
return view;
}
对于源列表,请使用NSOutlineViewShowHideButtonKey
。
界面生成器
该按钮已添加到列中,标识符设置为NSOutlineViewDisclosureButtonKey
。
NSOutlineView.h
/* The following NSOutlineView*Keys are used by the View Based NSOutlineView to create the "disclosure button" used to collapse and expand items. The NSOutlineView creates these buttons by calling [self makeViewWithIdentifier:owner:] passing in the key as the identifier and the delegate as the owner. Custom NSButtons (or subclasses thereof) can be provided for NSOutlineView to use in the following two ways:
1. makeViewWithIdentifier:owner: can be overridden, and if the identifier is (for instance) NSOutlineViewDisclosureButtonKey, a custom NSButton can be configured and returned. Be sure to set the button.identifier to be NSOutlineViewDisclosureButtonKey.
2. At design time, a button can be added to the outlineview which has this identifier, and it will be unarchived and used as needed.
When a custom button is used, it is important to properly set up the target/action to do something (probably expand or collapse the rowForView: that the sender is located in). Or, one can call super to get the default button, and copy its target/action to get the normal default behavior.
NOTE: These keys are backwards compatible to 10.7, however, the symbol is not exported prior to 10.9 and the regular string value must be used (i.e.: @"NSOutlineViewDisclosureButtonKey").
*/
APPKIT_EXTERN NSString *const NSOutlineViewDisclosureButtonKey NS_AVAILABLE_MAC(10_9); // The normal triangle disclosure button
APPKIT_EXTERN NSString *const NSOutlineViewShowHideButtonKey NS_AVAILABLE_MAC(10_9); // The show/hide button used in "Source Lists"
答案 1 :(得分:10)
这个答案是用OS X 10.7编写的,对于较新版本的OS X / macOS,请参阅WetFish's answer
不会调用该方法,因为它仅与基于单元格的大纲视图相关。
在基于视图的轮廓视图中,显示三角形是可扩展行的行视图中的常规按钮。我不知道它的添加位置,但确实如此,而NSView
的{{1}}方法正好处理了在其他地方添加的视图的情况。
因此,子类didAddSubview:
和覆盖NSTableRowView
,如下所示:
didAddSubview:
当然,大纲视图的委托必须实现-(void)didAddSubview:(NSView *)subview
{
// As noted in the comments, don't forget to call super:
[super didAddSubview:subview];
if ( [subview isKindOfClass:[NSButton class]] ) {
// This is (presumably) the button holding the
// outline triangle button.
// We set our own images here.
[(NSButton *)subview setImage:[NSImage imageNamed:@"disclosure-closed"]];
[(NSButton *)subview setAlternateImage:[NSImage imageNamed:@"disclosure-open"]];
}
}
才能返回新的行视图。
尽管有名称,outlineView:rowViewForItem:
的{{1}}仍然会被调用基于视图的轮廓视图,因此对于三角形的定位,您可能希望继承大纲视图并重写该方法。
答案 2 :(得分:2)
@ Monolo的答案的Swift2版本:
override func didAddSubview(subview: NSView) {
super.didAddSubview(subview)
if let sv = subview as? NSButton {
sv.image = NSImage(named:"icnArwRight")
sv.alternateImage = NSImage(named:"icnArwDown")
}
}
答案 3 :(得分:0)
对于Swift 4.2 macOS 10.14,@ WetFish的答案可以实现如下:
class SidebarView: NSOutlineView {
override func makeView(withIdentifier identifier: NSUserInterfaceItemIdentifier, owner: Any?) -> NSView? {
let view = super.makeView(withIdentifier: identifier, owner: owner)
if identifier == NSOutlineView.disclosureButtonIdentifier {
if let btnView = view as? NSButton {
btnView.image = NSImage(named: "RightArrow")
btnView.alternateImage = NSImage(named: "DownArrow")
// can set properties of the image like the size
btnView.image?.size = NSSize(width: 15.0, height: 15.0)
btnView.alternateImage?.size = NSSize(width: 15.0, height: 15.0)
}
}
return view
}
}
看起来很不错!