Как изменить цвет выбора кнопки NSSegmentedControl

Я пытаюсь найти способ изменить цвет выбранной кнопки управления. Возможно ли это путем создания подклассов NSSegmentedControl или NSSegmentedCell или любым другим способом? Если да, может ли кто-нибудь показать мне дорогу?


person memis    schedule 17.05.2017    source источник


Ответы (3)


Я сделал это по-другому, без переопределения, а просто с фильтром "False color". Он не идеален, так как немного меняет прозрачность цвета, но для меня это нормально.

class RLSegmentedControl: NSSegmentedControl {
init() {
    super.init(frame: NSZeroRect)
    addFilter()
}

required init?(coder: NSCoder) {
    super.init(coder: coder)
    addFilter()
}

func addFilter() {
    let colorFilter = CIFilter(name: "CIFalseColor")!
    colorFilter.setDefaults()
    colorFilter.setValue(CIColor(cgColor: NSColor.white.cgColor), forKey: "inputColor0")
    colorFilter.setValue(CIColor(cgColor: NSColor.black.cgColor), forKey: "inputColor1")

//        colorFilter.setValue(CIColor(cgColor: NSColor.yellow.cgColor), forKey: "inputColor0")
//        colorFilter.setValue(CIColor(cgColor: NSColor.black.cgColor), forKey: "inputColor1")

    self.contentFilters = [colorFilter]
}
}

введите здесь описание изображения

person brianLikeApple    schedule 18.09.2018

Вы можете создать подкласс NSSegmentedCell и переопределить метод drawSegment:

override func drawSegment(_ segment: Int, inFrame frame: NSRect, with controlView: NSView) {
    var color: NSColor
    if selectedSegment == segment {
        color = NSColor.red
    } else {
        color = NSColor.white
    }
    color.setFill()
    frame.fill()
    super.drawSegment(segment, inFrame: frame, with: controlView)
}
person Edson Guido    schedule 08.03.2018
comment
Работает с некоторыми ячейками сегмента, но половина ячеек в моем случае имеет только половину ширины рамки (вся ячейка не заполняется). - person wcochran; 24.10.2019

Вам нужно создать подкласс NSSegmentedCell и перезаписать следующий метод:

- (NSColor *)highlightColorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView

Из документации:

Возвращает цвет, который приемник использует при рисовании выделения.

Вы не должны предполагать, что ячейка обязательно захочет нарисовать себя со значением, возвращаемым от selectedControlColor. Ячейка может захотеть рисовать с другим цветом выделения выделения в зависимости от таких вещей, как состояние ключа его controlView.

person floschliep    schedule 18.05.2017
comment
Я пробовал это раньше. Этот метод NSCell никогда не вызывается в NSSegmentedCell, что указано и в документации. Вы не должны предполагать, что ячейка обязательно захочет нарисовать себя со значением, возвращаемым из selectedControlColor. Ячейка может захотеть рисовать с другим цветом выделения выделения в зависимости от таких вещей, как состояние ключа его controlView. - person memis; 19.05.2017
comment
Я бы зарегистрировал отчет об ошибке для этого. В документации говорится, что вы можете использовать этот метод для изменения цвета выделения, но ничего не говорится о том, что он не используется. Единственное решение, по-видимому, переопределяет -drawInteriorWithFrame:inView: и обрабатывает все рисунки самостоятельно. - person floschliep; 19.05.2017
comment
Не вижу этого метода в документации: developer.apple.com/documentation/appkit/nssegmentedcell - person wcochran; 24.10.2019
comment
@wcochran Это метод NSCell, который является суперклассом суперкласса NSSegmentedCell: developer.apple.com/documentation/appkit/nscell/ - person floschliep; 27.10.2019