对于cocoa,我将 NSTableView 设置为基于视图。选择行后,文本字段会将其颜色更改为白色。我怎么把它保持黑色?
我还应该注意,突出显示被设置为源列表(它在常规上做同样的事情)。
未选择的行
选定的行
我希望有类似iOS的状态配置:
这是在WWDC 2011 Session 120中提出的,但它有点延迟,所以我不打算使用它。它可能适用于其他人。
- (void)tableViewSelectionDidChange:(NSNotification *)notification
{
[tableView enumerateAvailableRowViewsUsingBlock:^(NSTableRowView *rowView, NSInteger row){
NSTableCellView *cellView = [rowView viewAtColumn:0];
if(rowView.selected){
cellView.textField.font = [NSFont boldSystemFontOfSize:14];
}else{
cellView.textField.font = [NSFont systemFontOfSize:14];
}
}];
}
答案 0 :(得分:16)
根据您需要执行此操作的原因,有两种方法。
您可以继承NSTableRowView
并覆盖-[NSTableRowView interiorBackgroundStyle]
以返回NSBackgroundStyleLight
。这将告诉单元格它们在浅色背景上并绘制黑色文本。
另一种方法是继承NSTableCellView
并覆盖-[NSTableCellView setBackgroundStyle:]
并自己设置颜色。
答案 1 :(得分:15)
无需自定义代码即可完成此任务。
只需在Interface Builder中将标签的颜色设置为“标签颜色”即可。只有当标签设置了“控制文本颜色”且位于NSTableCellView中时,自动白/黑物才会起作用。
答案 2 :(得分:14)
覆盖NSTableCellView并添加此方法以在选择单元格时更改文本颜色。
- (void) setBackgroundStyle:(NSBackgroundStyle)backgroundStyle
{
NSTableRowView *row = (NSTableRowView*)self.superview;
if (row.isSelected) {
self.textField.textColor = [NSColor blackColor];
} else {
self.textField.textColor = [NSColor whiteColor];
}
}
答案 3 :(得分:2)
我想出了一个不同的解决方案。如果Cocoa支持@IBOutletCollection,则可以对NSTableCellView进行子类化。因为那时我可以有一个Cell子类,其中包含单元格中所有NSTextField的数组。但由于我有多种具有不同数量的NSTextFields的单元格,所以我不喜欢这个选项。相反,我查看了Apple的NSTableCellView中backgroundStyle
属性的文档。
默认实现自动转发对所有实现setBackgroundStyle的子视图的调用:或者是NSControl,它们具有响应backgroundStyle的NSCell类。
如果我的TextField实现了setBackgroundStyle,那么当单元格选择发生变化时,它们会收到通知。但是,这种背景样式的转发不是递归的。因为我的NSTextFields在NSStackViews中,所以他们没有收到消息。为了解决这个问题,我刚刚编写了一个扩展来在所有NSView上实现setBackgroundStyle。它只是转发消息。最后,我添加了NSTextField的扩展以实现此方法。从这个扩展名,我改变文本颜色并调用super。这个解决方案也很好,因为不需要子类。没有NSTableCellView或NSTextField的子类。
将此功能添加到所有视图和所有NSTextField可能会导致NSTextFields出现问题,这些问题不在NSTableViews中,意外地改变了颜色。但到目前为止,只有我的TableViews / OutlineViews中的那些正在改变颜色,这正是我想要的。如果您看到文本字段改变了您不期望的颜色,您可能希望子类化NSTextField并仅在该子类上实现setBackgroundStyle覆盖,而不是将其添加到所有NSTextFields。
我使用的Swift 3中的代码粘贴在下面。
extension NSView {
func setBackgroundStyle(_ newValue: NSBackgroundStyle) {
for view in self.subviews {
view.setBackgroundStyle(newValue)
}
}
}
extension NSTextField {
override func setBackgroundStyle(_ newValue: NSBackgroundStyle) {
switch newValue {
case .dark:
self.textColor = NSColor.controlLightHighlightColor
case .light, .lowered, .raised:
self.textColor = NSColor.labelColor
}
super.setBackgroundStyle(newValue)
}
}
答案 4 :(得分:1)
对于我的Swift应用程序,以上所有内容似乎都没有正常工作。此方法正确处理NSTableView失去焦点,当窗口不是关键窗口但仍然选中单元格时。
在NSTableCellView
子类中使用以下内容:
override var backgroundStyle: NSView.BackgroundStyle {
willSet {
if newValue == .dark {
title.textColor = NSColor.white
} else {
title.textColor = NSColor.labelColor
}
}
}
答案 5 :(得分:0)
根据@ sabes的回答,我创建了这个NSTextFieldCell
子类,您可以在选择或取消选择行时设置自定义文本颜色。您可以在IB中设置相关文本字段单元的子类。
@interface SNBlueTextFieldCell : NSTextFieldCell
@end
@implementation SNBlueTextFieldCell
- (void)setBackgroundStyle:(NSBackgroundStyle)backgroundStyle {
[self setTextColor:(backgroundStyle==NSBackgroundStyleDark ? [NSColor blackColor] : [NSColor blueColor])];
}
@end
答案 6 :(得分:0)
在 macOS 11 或更高版本中,.dark
和 .light
背景样式已弃用。但您可以改用 .emphased
:
override var backgroundStyle: NSView.BackgroundStyle {
willSet {
textField.textColor = newValue == .emphasized ? .labelColor : .secondaryLabelColor
}
}
在示例中,.labelColor
是选定的颜色,.secondaryLabelColor
是未选定的颜色。