NSPredicateEditor的超类NSRuleEditor公开了一个selectedRowIndexes: IndexSet属性(以及相应的selectRowIndexes(IndexSet, byExtendingSelection: Bool)设置器)。在此属性上添加一个观察者表明,每当单击谓词编辑器中的某一行时,该属性都会发生更改。但是,没有显示该行被选中或取消选中的可视指示。
我想在我的谓词编辑器中直观地突出显示选定的行,但是几乎没有子类或委托方法可以实现视图绘制方法来定制编辑器的外观。有没有人能提出一些建议,让用户知道规则编辑器的行已经被选中了?
发布于 2018-11-03 21:05:50
在NSPredicateEditorRowTemplate类中,您将发现一个名为templateViews的属性,正如苹果的文档中所提到的,您可以覆盖该属性以返回其他视图。返回一个附加视图,并将其用作选择的指示器。
/*返回放置在行中的视图列表。NSPopUpButtons被特别对待,因为多个模板的项被合并在一起;其他视图是按原样添加的。开发人员可以覆盖它,以返回默认视图之外的视图或代替默认视图。*/
我在几年前定制了NSPredicateEditorRowTemplate来实现一个星级控件,但我必须查找代码以及它到底是如何完成的。
希望这能有所帮助。
发布于 2018-11-03 22:24:42
使用NSRuleEditor测试的未记录的和粗糙的:观察选择的变化并设置行片的背景颜色。在NSRuleEditorViewSliceRow上创建一个类别并实现drawRect:。例如
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
change:(NSDictionary *)change context:(void *)context {
if (context != &myRuleEditorObservingContext)
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
else
{
// backgroundColor is a property or ivar of NSRuleEditorViewSlice and subclass NSRuleEditorViewSliceRow
NSArray *slices = [ruleEditor valueForKey:@"slices"];
[slices makeObjectsPerformSelector:@selector(setBackgroundColor:) withObject:nil];
NSArray *selectedSlices = [slices objectsAtIndexes:[ruleEditor selectedRowIndexes]];
[selectedSlices makeObjectsPerformSelector:@selector(setBackgroundColor:) withObject:[NSColor selectedControlColor]];
}
}
@interface NSRuleEditorViewSliceRow : NSObject
@end
@interface NSRuleEditorViewSliceRow(Draw)
@end
@implementation NSRuleEditorViewSliceRow(Draw)
- (void)drawRect:(NSRect)dirtyRect {
NSColor *aColor = [(id)self backgroundColor];
if (aColor) {
[aColor set];
NSRectFill(dirtyRect);
}
}
@end发布于 2018-11-04 02:38:17
感谢你到目前为止的所有答案。这是我已经决定的,但我担心它的脆弱性。如有任何改进建议,我们将不胜感激。…
class RowHighlightingRuleEdtitor : NSRuleEditor {
var highlightsSelectedRow: Bool = true
override func didChangeValue(forKey key: String) {
super.didChangeValue(forKey: key)
if key == "selectedRowIndexes" {
// Whenever we change the selection, re-layout the view.
self.needsLayout = true
}
}
override func layout() {
super.layout()
if !highlightsSelectedRow { return }
let selected = self.selectedRowIndexes
// Of all the fragile ways to check if the view is a row, checking the class name is the easiest.
// Possible alternative solution: check for the existence of the add-new-row button.
func viewIsEditorRow(_ view: NSView) -> Bool { return view.className == "NSRuleEditorViewSliceRow" }
// Sorting must be done because the order of the rows does not necessarily correspond to the order of the subviews.
// NSRuleEditorViewSliceRow's superclass NSRuleEditorViewSlice has a rowIndex property, but it is private
// Possible alternative solution: use valueForKey("rowIndex") to get the index
func rowOrder(lhs: NSView, rhs: NSView) -> Bool { return lhs.frame.origin.y < rhs.frame.origin.y }
// subview is NSRuleEditorViewSliceHolder and holds NSBannerView and NSRuleEditorViewSliceRow instances
for (index, rowView) in subviews.flatMap({ $0.subviews }).filter(viewIsEditorRow).sorted(by: rowOrder).enumerated() {
if selected.contains(index) {
// we use *secondary*SelectedControlColor because the rule editor comonent is not actually focusable
rowView.layer?.backgroundColor = NSColor.secondarySelectedControlColor.cgColor
} else {
rowView.layer?.backgroundColor = nil
}
}
}
}https://stackoverflow.com/questions/53131204
复制相似问题