Ios 如何更新嵌入到UIKit中的SwiftUI视图?
我正在寻找一个等效于AppKit的UIKit,这样我就可以在UIKit中嵌入一个SwiftUI视图。不幸的是,UIKit没有与Ios 如何更新嵌入到UIKit中的SwiftUI视图?,ios,swift,uikit,swiftui,Ios,Swift,Uikit,Swiftui,我正在寻找一个等效于AppKit的UIKit,这样我就可以在UIKit中嵌入一个SwiftUI视图。不幸的是,UIKit没有与NSHostingView等效的类。我们所拥有的最接近的,相当于,命名为。因为视图控制器包含一个视图,所以我们应该能够,然后抓取视图并直接使用它 这说明这是在UIKit中嵌入SwiftUI视图的方法。然而,它们通常无法解释如何从UIKit进行通信➡️ 快捷键。例如,假设我实现了一个充当进度条的SwiftUI视图,我希望定期更新进度。我希望我的遗留/UIKit代码更新Swi
NSHostingView
等效的类。我们所拥有的最接近的,相当于,命名为。因为视图控制器包含一个视图,所以我们应该能够,然后抓取视图
并直接使用它
这说明这是在UIKit中嵌入SwiftUI视图的方法。然而,它们通常无法解释如何从UIKit进行通信➡️ 快捷键。例如,假设我实现了一个充当进度条的SwiftUI视图,我希望定期更新进度。我希望我的遗留/UIKit代码更新SwiftUI视图以显示新的进度
接近解释如何操作嵌入式视图内容的人建议我们使用@ObservedObject
:
import UIKit
import SwiftUI
import Combine
class CircleModel: ObservableObject {
var didChange = PassthroughSubject<Void, Never>()
var text: String { didSet { didChange.send() } }
init(text: String) {
self.text = text
}
}
struct CircleView : View {
@ObservedObject var model: CircleModel
var body: some View {
ZStack {
Circle()
.fill(Color.blue)
Text(model.text)
.foregroundColor(Color.white)
}
}
}
class ViewController: UIViewController {
private weak var timer: Timer?
private var model = CircleModel(text: "")
override func viewDidLoad() {
super.viewDidLoad()
addCircleView()
startTimer()
}
deinit {
timer?.invalidate()
}
}
private extension ViewController {
func addCircleView() {
let circleView = CircleView(model: model)
let controller = UIHostingController(rootView: circleView)
addChild(controller)
controller.view.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(controller.view)
controller.didMove(toParent: self)
NSLayoutConstraint.activate([
controller.view.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.5),
controller.view.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.5),
controller.view.centerXAnchor.constraint(equalTo: view.centerXAnchor),
controller.view.centerYAnchor.constraint(equalTo: view.centerYAnchor)
])
}
func startTimer() {
var index = 0
timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { [weak self] _ in
index += 1
self?.model.text = "Tick \(index)"
}
}
}
导入UIKit
导入快捷键
进口联合收割机
类CircleModel:ObservableObject{
var didChange=PassthroughSubject()
变量文本:字符串{didSet{didChange.send()}
初始化(文本:字符串){
self.text=文本
}
}
结构CircleView:视图{
@观测对象var模型:CircleModel
var body:一些观点{
ZStack{
圈()
.填充(颜色.蓝色)
文本(model.Text)
.foregroundColor(颜色.白色)
}
}
}
类ViewController:UIViewController{
专用弱var定时器:定时器?
private var model=CircleModel(文本:“”)
重写func viewDidLoad(){
super.viewDidLoad()
addCircleView()
startTimer()
}
脱硝{
计时器?.invalidate()
}
}
专用扩展视图控制器{
func addCircleView(){
设circleView=circleView(模型:模型)
let controller=UIHostingController(rootView:circleView)
addChild(控制器)
controller.view.translatesAutoResizezingMaskintoConstraints=false
view.addSubview(controller.view)
controller.didMove(toParent:self)
NSLayoutConstraint.activate([
controller.view.widthAnchor.constraint(等式:view.widthAnchor,乘数:0.5),
controller.view.heightAnchor.constraint(等式:view.heightAnchor,乘数:0.5),
controller.view.centerXAnchor.constraint(等于:view.centerXAnchor),
controller.view.centerYAnchor.constraint(等式:view.centerYAnchor)
])
}
func startTimer(){
var指数=0
timer=timer.scheduledTimer(withTimeInterval:1,repeats:true){[weak self]\uuin
指数+=1
self?.model.text=“勾选\(索引)”
}
}
}
这似乎是有道理的,因为计时器应该触发更新视图的一系列事件:
self?.model.text=“勾选1”
(在ViewController.startTimer()
中)didChange.send()
(在CircleModel.text.didSet
中)CircleView.body中
)didChange.send()
从不触发重新运行CircleView.body
如何从UIKit>SwiftUI进行通信以操作嵌入在UIKit中的SwiftUI视图?您只需扔掉该自定义主题,并使用标准的
@Published
,如下所示
class CircleModel: ObservableObject {
@Published var text: String
init(text: String) {
self.text = text
}
}
测试日期:Xcode 11.2/iOS 13.2您的信息已过期
ObservableObject
已更改(而iOS 13.0仍处于测试阶段),要求使用objectWillChange
发布者,而不是didChange
发布者。Asperi的回答显示了一种更简单的方法来实现您的可观察对象
,方法是让它从其@已发布的
属性中合成自己的发布者。