我正在嘗試向macos_ui添加一項功能,該功能允許用戶啟動本機 macOS 顏色選擇器并通過EventChannel.
我能夠啟動選擇器(Cocoa's NSColorPanel),但顏色選擇不會流回來。當我通過 XCode 運行示例應用程式時,我可以看到顏色選擇已注冊,但它們似乎沒有通過EventChannel. 處理這個問題的正確方法是什么?考慮到它們發生在原生 macOS 視圖中,甚至有可能將這些事件流回 Flutter 嗎?
這是我到目前為止的 Swift 代碼:
MacosUIPlugin.swift
import Cocoa
import FlutterMacOS
public class MacOSUiPlugin: NSObject, FlutterPlugin, FlutterStreamHandler {
private let colorPanelProvider: ColorPanelProvider
private var eventSink: FlutterEventSink?
init(colorPanelProvider: ColorPanelProvider) {
self.colorPanelProvider = colorPanelProvider
super.init()
}
public static func register(with registrar: FlutterPluginRegistrar) {
let channel = FlutterMethodChannel(
name: "dev.groovinchip.macos_ui",
binaryMessenger: registrar.messenger)
let colorSelectionChannel = FlutterEventChannel(
name: "dev.groovinchip.macos_ui/color_panel",
binaryMessenger: registrar.messenger)
let colorPanelProvider = ColorPanelProvider()
let instance = MacOSUiPlugin(colorPanelProvider: colorPanelProvider)
colorSelectionChannel.setStreamHandler(instance)
registrar.addMethodCallDelegate(instance, channel: channel)
}
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
switch call.method {
case "color_panel":
colorPanelProvider.openPanel()
result(true)
default:
result(FlutterMethodNotImplemented)
}
}
public func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? {
print("listening to MacosUIPluginEvents")
eventSink = events
//colorPanelProvider.startStream()
return nil
}
public func onCancel(withArguments arguments: Any?) -> FlutterError? {
eventSink = nil
return nil
}
}
extension NSColor {
var hexString: String {
let red = Int(round(self.redComponent * 0xFF))
let green = Int(round(self.greenComponent * 0xFF))
let blue = Int(round(self.blueComponent * 0xFF))
let hexString = NSString(format: "#XXX", red, green, blue)
return hexString as String
}
}
ColorPanelProvider.swift
import FlutterMacOS
class ColorPanelProvider: NSObject, FlutterStreamHandler {
var eventSink: FlutterEventSink?
let colorPanel = NSColorPanel.shared
func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? {
print("listening to ColorPanelProvider events")
eventSink = events
return nil
}
func openPanel() {
colorPanel.setTarget(self)
colorPanel.setAction(#selector(startStream))
colorPanel.makeKeyAndOrderFront(self)
colorPanel.isContinuous = true
startStream()
}
@objc private func currentColor() -> String {
print("currentColor: \(colorPanel.color.asFlutterHexString)")
return colorPanel.color.asFlutterHexString
}
@objc public func startStream() {
print("starting ColorPanelProvider stream")
NotificationCenter.default.addObserver(
self,
selector: #selector(currentColor),
name: NSColorPanel.colorDidChangeNotification,
object: colorPanel)
eventSink?(currentColor())
}
func onCancel(withArguments arguments: Any?) -> FlutterError? {
eventSink = nil
return nil
}
}
extension NSColor {
var asFlutterHexString: String {
let red = Int(round(self.redComponent * 0xFF))
let green = Int(round(self.greenComponent * 0xFF))
let blue = Int(round(self.blueComponent * 0xFF))
let hexString = NSString(format: "#XXX", red, green, blue)
return hexString.replacingOccurrences(of: "#", with: "0xFF") as String
}
}
uj5u.com熱心網友回復:
你一直在正確的軌道上,但有一些事情需要修復。有三件事:
- 在
MacosUIPlugin.swift你需要聽的colorChannelProvider而不是instance你的register功能。所以你需要更改以下行
colorSelectionChannel.setStreamHandler(instance)
對此:
colorSelectionChannel.setStreamHandler(colorChannelProvider)
- 在
ColorPanelProvider.swift你聽的顏色變化startStream。雖然這是正確的方法,但您必須提交colorPanel發送這些更改的 ,以便該函式可以使用 訪問顏色colorPanel.color。函式簽名應如下所示:
@objc public func startStream(colorPanel: NSColorPanel)
- 當您將該方法注冊為目標以從in
startStream接收更新時,您需要對其進行設定,以便正確呼叫它。因此,將方法的第二行更改為如下所示,一切都像魅力一樣作業:colorPanelopenPanel()
colorPanel.setAction(#selector(startStream(colorPanel:)))
希望這將解決所有問題。如果還有問題,請告訴我。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/467973.html
標籤:扑 可可 颤振插件 nscolorpanel 事件通道
