我正在尝试将iOS应用程序移植到Mac上,并且在转换过程中遇到了一些问题。其中之一是NSTableView
的自定义。基于NSCell
的{{1}},NSTableRowView
和自定义NSView
之间究竟有什么区别?我最初开始使用基于NSTableview
的视图,但我很快就注意到我必须自己处理选择。我无法取消它,所以我继续使用NSTableView
,奇怪的是,它不会调用我的自定义NSTableRowView
的初始化程序。
我基本上只想要一个具有自定义内容的自定义表格视图单元格,这是可选择的。最好的方法是什么?
在iOS上,我只是将NSTableRowView
子类化并设置其selectedView属性。在Mac上,这似乎比这更复杂。
答案 0 :(得分:18)
我实际上刚刚找到(在侧边栏中)这个问题,建议继承NSTableRowView
。我之前已经这样做了,但它没有用。我再次尝试过,而且很令人惊讶它现在有效......
然而,这个答案并不是很有用,所以我会尽力说明我为完成这项工作所做的工作。
首先,我实现了以下NSTableView委托方法并返回nil!:
- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row{
return nil;
}
为了使用基于视图(我猜NSTableViewRow被视为基于视图的表...)表,您必须实现此方法。我不太确定我可能做错了什么,但是如果没有这种方法,我的单元格就不会显示了!
确保不要让NSTableView通过设置此属性来处理任何选择:
yourNSTableView.selectionHighlightStyle = NSTableViewSelectionHighlightStyleNone;
好的,现在我们要使用以下委托方法设置我们的单元格:
-(NSTableRowView *)tableView:(NSTableView *)tableView rowViewForRow:(NSInteger)row{
static NSString *cellID = @"cell_identifier";
//use this if you want to reuse the cells
CustomTableRowView *result = [tableView makeViewWithIdentifier:cellID owner:self];
if (result == nil) {
result = [[CustomTableRowView alloc] initWithFrame:NSMakeRect(0, 0, self.frame.size.width, 80)];
result.identifier = cellID;
}
result.data = [tableData objectAtIndex:row];
// Return the result
return result;
}
好的,现在子类NSTableRowView
并实现/覆盖以下两种方法:
首先,我们必须覆盖setSelected:
,以便在选中时让单元格重绘其背景。所以这就是:
-(void)setSelected:(BOOL)selected{
[super setSelected:selected];
[self setNeedsDisplay:YES];
}
如前所述,我们调用setNeedsDisplay:
以便单元格重绘其背景。
最后,绘图代码。像这样覆盖方法drawBackgroundInRect:
:
-(void)drawBackgroundInRect:(NSRect)dirtyRect{
if (!self.selected) {
[[NSColor clearColor] set];
} else {
[someColor set];
}
NSRectFill(dirtyRect);
}
答案 1 :(得分:3)
使用以下代码响应NSTableViewDelegate协议tableViewSelectionDidChange:
获取所选行的NSTableRowView并在其上调用setEmphasized方法。当setEmphasized设置为YES时,您将获得蓝色突出显示,如果不是,则获得灰色突出显示。
-(void)tableViewSelectionDidChange:(NSNotification *)aNotification {
NSInteger selectedRow = [myTableView selectedRow];
NSTableRowView *myRowView = [myTableView rowViewAtRow:selectedRow makeIfNecessary:NO];
[myRowView setSelectionHighlightStyle:NSTableViewSelectionHighlightStyleRegular];
[myRowView setEmphasized:NO];
}
为了避免蓝色的跳舞效果,然后灰色设置
[_tableView setSelectionHighlightStyle:NSTableViewSelectionHighlightStyleNone];
答案 2 :(得分:2)
the_critic在Swift中的解决方案:(使用XCode 7 beta3,Swift 2.0测试)
class CustomTableRowView: NSTableRowView {
override var selected: Bool {
willSet(newValue) {
super.selected = newValue;
needsDisplay = true
}
}
override func drawBackgroundInRect(dirtyRect: NSRect) {
let context: CGContextRef = NSGraphicsContext.currentContext()!.CGContext
if !self.selected {
CGContextSetFillColorWithColor(context, NSColor.clearColor().CGColor)
} else {
CGContextSetFillColorWithColor(context, NSColor.redColor().CGColor)
}
CGContextFillRect(context, dirtyRect)
}
}
的ViewController:
class ViewController: NSViewController, NSTableViewDelegate, NSTableViewDataSource {
// [...]
func tableView(tableView: NSTableView, rowViewForRow row: Int) -> NSTableRowView? {
guard let rowView = tableView.makeViewWithIdentifier("RowView", owner: nil) as! CustomTableRowView? else {
let rowView = CustomTableRowView()
rowView.identifier = "RowView"
return rowView
}
return rowView
}
}
答案 3 :(得分:0)