簡體   English   中英

突出顯示NSPredicateEditor中的選定行

[英]Highlighting selected rows in an NSPredicateEditor

NSPredicateEditor的超類NSRuleEditor公開了selectedRowIndexes: IndexSet屬性(以及相應的selectRowIndexes(IndexSet, byExtendingSelection: Bool) setter)。 在此屬性上添加觀察者表明,只要在謂詞編輯器中單擊一行,它的確會更改。 但是,沒有視覺指示表明該行已被選擇或取消選擇。

我想在謂詞編輯器中直觀地突出顯示選定的行,但是幾乎沒有視圖繪圖方法可以子類化或委托方法來實現以自定義編輯器的外觀。 任何人都可以建議某種方式來傳達使用規則編輯器行已被選擇的用途嗎?

在NSPredicateEditorRowTemplate類中,您將找到一個名為templateViews的屬性。如Apple文檔中所述,您可以覆蓋此屬性以返回其他視圖。 返回另一個視圖,並將其用作選擇的指示。

/ *返回放置在行中的視圖列表。 NSPopUpButtons的特殊之處在於將多個模板的項目合並在一起; 其他視圖按原樣添加。 開發人員可以覆蓋此設置,以返回默認視圖或代替默認視圖。 * /

幾年前,我自定義了NSPredicateEditorRowTemplate來實現星級評定控件,但必須查找代碼及其精確實現方式。

希望這可以幫助。

無證件,hacky,使用NSRuleEditor進行了NSRuleEditor :觀察選擇更改並設置行切片的背景顏色。 NSRuleEditorViewSliceRow上創建一個類別,並實現drawRect: NSRuleEditorViewSliceRow 例如

- (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

到目前為止,感謝您提供所有答案。 這就是我所確定的,但我擔心其脆弱性。 任何改進的建議將不勝感激...

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
            }
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM