将自定义自定义 UIKit 事件从自定义 UIKit 控件公开到 SwiftUI



我有一个自定义 UIKit 控件,它有一个自定义事件。有谁知道如何使用 Combine 框架向 SwiftUI 公开此事件?

我可以使用 Combine 的 UIViewRepresentable 渲染控件,但找不到将自定义事件或内部 UIKit 事件更改的值公开到 SwiftUI 的方法。

下面是此问题的具体示例:

我正在使用这个自定义 UIKit 滑块控件(因为它支持多个旋钮/值(:

https://github.com/yonat/MultiSlider

它有一个滑块更改事件,用于更新当前值。 如何使用 Combine 向 SwiftUI 公开此值?

我不能简单地传入@ObservedObject因为UIViewRepresentable不允许这样做。我也无法从事件处理程序更新@Binding变量,因为 UIKit 事件处理程序标有 @objc 并且它不喜欢它。

这似乎是一个非常常见的用例。我希望苹果对此有一个标准的解决方案。但是,我根本找不到真正适用于这些类型场景的产品。我在这里错过了什么?

我认为,这可以解决您的问题:

final class MultiSliderSwiftUI: UIViewRepresentable {
private let valueChanged: ([CGFloat]) -> Void
init(valueChanged: @escaping ([CGFloat]) -> Void) {
self.valueChanged = valueChanged
}
func makeUIView(context: UIViewRepresentableContext<MultiSliderSwiftUI>) -> MultiSlider {
let slider = MultiSlider()
slider.addTarget(self, action: #selector(sliderChanged(_:)), for: .valueChanged)
return slider
}
func updateUIView(_ uiView: MultiSlider, context: UIViewRepresentableContext<MultiSliderSwiftUI>) {
}
@objc func sliderChanged(_ slider: MultiSlider) {
valueChanged(slider.value)
}
}

如果你不喜欢为 SwiftUI 视图创建final class,你可以这样做:

struct MultiSliderSwiftUI: UIViewRepresentable {
private let events: MultiSliderEvents
init(valueChanged: @escaping ([CGFloat]) -> Void) {
events = MultiSliderEvents(valueChanged: valueChanged)
}
func makeUIView(context: UIViewRepresentableContext<MultiSliderSwiftUI>) -> MultiSlider {
let slider = MultiSlider()
events.addEvents(for: slider)
return slider
}
func updateUIView(_ uiView: MultiSlider, context: UIViewRepresentableContext<MultiSliderSwiftUI>) {
}
}
class MultiSliderEvents {
private let valueChanged: ([CGFloat]) -> Void
init(valueChanged: @escaping ([CGFloat]) -> Void) {
self.valueChanged = valueChanged
}
func addEvents(for slider: MultiSlider) {
slider.addTarget(self, action: #selector(sliderChanged(_:)), for: .valueChanged)
}
@objc func sliderChanged(_ slider: MultiSlider) {
valueChanged(slider.value)
}
}

在这两种方式中,您都可以使用它MultiSliderSwiftUI例如Button

MultiSliderSwiftUI { value in
print("(value)")
}

请尝试swiftui分支中的MultiValueSlider,并告诉我它是否适合您。
示例用法:多滑块演示。

(我是包作者(

最新更新