将自定义 UIKit 事件从自定义 UIKit 控件公开到 SwiftUI
Posted
技术标签:
【中文标题】将自定义 UIKit 事件从自定义 UIKit 控件公开到 SwiftUI【英文标题】:Exposing custom custom UIKit events from custom UIKit controls to SwiftUI 【发布时间】:2019-10-07 10:33:45 【问题描述】:我有一个具有自定义事件的自定义 UIKit 控件。有谁知道如何使用 Combine 框架将此事件公开给 SwiftUI?
我可以使用 Combine 的 UIViewRepresentable 呈现控件,但找不到将自定义事件或内部 UIKit 事件更改的值公开给 SwiftUI 的方法。
这是这个问题的一个具体例子:
我正在使用这个自定义 UIKit 滑块控件(因为它支持多个旋钮/值):
https://github.com/yonat/MultiSlider
它有一个更新当前值的 sliderChanged 事件。 如何使用 Combine 将此值公开给 SwiftUI?
我不能简单地传入 @ObservedObject,因为 UIViewRepresentable 不允许这样做。我也无法从事件处理程序更新 @Binding 变量,因为 UIKit 事件处理程序标有 @objc 并且它不喜欢它。
这似乎是一个非常常见的用例。我希望苹果有一个标准的解决方案。但是,我根本找不到真正适用于这些类型场景的。我在这里错过了什么?
【问题讨论】:
【参考方案1】:我认为,这可以解决您的问题:
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)")
【讨论】:
感谢您的回复!非常感谢!【参考方案2】:请尝试swiftui
分支中的MultiValueSlider,并告诉我它是否适合您。
用法示例:MultiSliderDemo。
(我是包作者)
【讨论】:
感谢您的回复!非常感谢!以上是关于将自定义 UIKit 事件从自定义 UIKit 控件公开到 SwiftUI的主要内容,如果未能解决你的问题,请参考以下文章