Как правильно подключить NSColorPanel к серверу, чтобы избежать перегрузки - PullRequest
2 голосов
/ 09 января 2020

Я использую NSColorPanel для изменения цвета вида. Цвет этого представления также сохраняется в базе данных (Firestore).

import AppKit

class ColorPanel {

    static var shared = ColorPanel()

    private var stage: DB.Stage.Document? = nil

    private let cp = NSColorPanel.shared

    init() {
        cp.setTarget(self)
        cp.setAction(#selector(colorDidChange(sender:)))
        cp.isContinuous = false
    }

    func show(stage: DB.Stage.Document) {
        self.stage = stage
        cp.makeKeyAndOrderFront(nil)
    }

    @objc func colorDidChange(sender: NSColorPanel) {
        guard let stage = stage else { return }
        stage.data?.color.red = Double(sender.color.redComponent)
        stage.data?.color.green = Double(sender.color.greenComponent)
        stage.data?.color.blue = Double(sender.color.blueComponent)
        stage.update()
    }
}

Проблема состоит в том, что я хотел бы установить значение isContinuos в значение true, чтобы мой вид изменял цвет в реальном времени, но отправляет слишком много обновлений на сервере, поэтому я был вынужден установить значение false.

Есть способ решить эту проблему? Мне просто нужно сделать обновление, когда я закончу sh перетаскивание, но я не знаю как.

ps Для вызова ColorPanel в моем представлении SwiftUI я делаю:

ColorPanel.shared.show(stage: stage)

1 Ответ

1 голос
/ 09 января 2020

Пожалуйста, попробуйте подход, который я бы использовал. Отказ от ответственности: не проверено из-за отсутствия настройки Firestore

import Combine

class ColorPanel {

    static var shared = ColorPanel()

    private var stage: DB.Stage.Document? = nil

    private let cp = NSColorPanel.shared

    private var subscriber: AnyCancellable?
    private let publisher =
        PassthroughSubject<NSColor, Never>()
            .throttle(for: 10, scheduler: RunLoop.main, latest: true)

    init() {
        cp.setTarget(self)
        cp.setAction(#selector(colorDidChange(sender:)))
        cp.isContinuous = true
    }

    func show(stage: DB.Stage.Document) {
        self.stage = stage
        self.subscriber = nil

        if stage != nil {
            self.subscriber = self.publisher
                .sink { _ in
                    self.stage.update() // << be called once per 10 seconds
                }
        }
        cp.makeKeyAndOrderFront(nil)
    }

    @objc func colorDidChange(sender: NSColorPanel) {
        guard let stage = stage else { return }
        stage.data?.color.red = Double(sender.color.redComponent)
        stage.data?.color.green = Double(sender.color.greenComponent)
        stage.data?.color.blue = Double(sender.color.blueComponent)

        self.publisher.upstream.send(sender.color)
    }
}
...