我正在使用NSOutlineView进行项目,似乎无法弄清楚两件事:
是否有某种用于此的NSOutlineView Delegate方法?或者它需要一个子类?
答案 0 :(得分:40)
你在这里遇到了合适的人选。一周前我不得不解决这个问题。
删除显示三角形:在frameOfOutlineCellAtRow:
子类中实现NSOutlineView
方法并返回NSZeroRect
(仅当您要隐藏该特定行的三角形时,当然。)
- (NSRect)frameOfOutlineCellAtRow:(NSInteger)row {
return NSZeroRect;
}
禁用缩进:大纲视图的标准布局保留最左侧的空间以绘制三角形,以防项目可扩展。但您可以通过指定不同的绘图框来覆盖单个项目。您也可以通过响应此消息在您的子类中执行此操作:
- (NSRect)frameOfCellAtColumn:(NSInteger)column row:(NSInteger)row {
NSRect superFrame = [super frameOfCellAtColumn:column row:row];
if ((column == 0) /* && isGroupRow */) {
return NSMakeRect(0, superFrame.origin.y, [self bounds].size.width, superFrame.size.height);
}
return superFrame;
}
答案 1 :(得分:35)
为了将来参考,在可扩展的NSOutlineView项中隐藏显示三角形的最简洁和最简单的方法是在您的代理中实施outlineView:shouldShowOutlineCellForItem:协议的NSOutlineViewDelegate方法:
-(BOOL)outlineView:(NSOutlineView *)outlineView shouldShowOutlineCellForItem:(id)item
{
// replace this with your logic to determine whether the
// disclosure triangle should be hidden for a particular item
return [item hidesDisclosureTriangle];
}
答案 2 :(得分:8)
我必须将上述两种方法结合起来,因为outlineView:shouldShowOutlineCellForItem:
单独不会删除为显示三角形保留的空间(它确实会删除三角形本身)。
代表:
- (BOOL)outlineView:(NSOutlineView *)outlineView shouldShowOutlineCellForItem:(id)item {
return NO;
}
NSOutlineView的子类:
@implementation ExpandedOutlineView
#define kOutlineCellWidth 11
#define kOutlineMinLeftMargin 6
- (NSRect)frameOfCellAtColumn:(NSInteger)column row:(NSInteger)row {
NSRect superFrame = [super frameOfCellAtColumn:column row:row];
if (column == 0) {
// expand by kOutlineCellWidth to the left to cancel the indent
CGFloat adjustment = kOutlineCellWidth;
// ...but be extra defensive because we have no fucking clue what is going on here
if (superFrame.origin.x - adjustment < kOutlineMinLeftMargin) {
NSLog(@"%@ adjustment amount is incorrect: adjustment = %f, superFrame = %@, kOutlineMinLeftMargin = %f", NSStringFromClass([self class]), (float)adjustment, NSStringFromRect(superFrame), (float)kOutlineMinLeftMargin);
adjustment = MAX(0, superFrame.origin.x - kOutlineMinLeftMargin);
}
return NSMakeRect(superFrame.origin.x - adjustment, superFrame.origin.y, superFrame.size.width + adjustment, superFrame.size.height);
}
return superFrame;
}
@end
结果:
答案 3 :(得分:2)
使用PXSourceList。这是你正在寻找的风格非常好的api。
答案 4 :(得分:0)
指定每个级别的意图的正确方法是覆盖NSOutlineView的indentationPerLevel
。
class NoIndentOutlineView: NSOutlineView {
override var indentationPerLevel: CGFloat {
get {
return 0;
}
set {
// Do nothing
}
}
}
这将确保孩子的缩进与父母相同。
答案 5 :(得分:0)
这与隐藏披露按钮有关。如果您希望将其全局隐藏在可扩展项目上,则可以执行以下操作:
extension NSOutlineView {
override open func makeView(withIdentifier identifier: NSUserInterfaceItemIdentifier, owner: Any?) -> NSView? {
if identifier == NSOutlineView.disclosureButtonIdentifier {
return nil
} else {
return super.makeView(withIdentifier: identifier, owner: owner)
}
}
}
否则,您可以继承NSOutlineView
的子类并覆盖makeView
函数。
我知道q是obj-c。我只需要解决这个问题,我的项目就很快。
答案 6 :(得分:0)
对于OP提出的问题,以上给出了很好的答案-删除了显示三角形及其占用的空间。要实现“列表不扩展且所有项目都在同一级别”(即它们要达到的效果),您需要做的就是将大量顶级项目放入用作数据的数组中源和实现
func outlineView(_ outlineView: NSOutlineView, isItemExpandable item: Any) -> Bool {
return false
}
答案 7 :(得分:-3)
我在Swift中试过这个。它只是有效。我不知道这是否是一种正确的方式。在Obj-C中应该有相同的东西:
extension NSTableRowView {
override open func layout() {
super.layout()
if let cell = subviews.first as? NSTableCellView, cell.objectValue is <YourHeaderCellClass> {
subviews.first?.setFrameOrigin(NSZeroPoint)
}
}
}
确保在datasource方法中返回YourHeaderCellClass项。
func outlineView(_ outlineView: NSOutlineView, child index: Int, ofItem item: Any?) -> Any