Sen*_*ful 5 uikit ios swift swiftui
我正在为 UIKit寻找 AppKit 的NSHostingView的等效项,以便我可以在 UIKit 中嵌入 SwiftUI 视图。不幸的是,UIKit 没有与NSHostingView. 我们所拥有的最接近NSHostingController的等效项,名为UIHostingController。由于视图控制器包含视图,我们应该能够调用适当的 UIViewController 嵌入方法,然后view直接抓取并使用它。
目前 有 许多 文章解释,这是方式嵌入里面的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)"
}
}
}
Run Code Online (Sandbox Code Playgroud)
这似乎是有道理的,因为计时器应该触发更新视图的一系列事件:
self?.model.text = "Tick 1"(在ViewController.startTimer())。didChange.send()(在CircleModel.text.didSet)Text(model.text)(在CircleView.body)正如您通过指标(指定是否运行某事)所见,问题在于didChange.send()永远不会触发CircleView.body.
如何从 UIKit > SwiftUI 进行通信以操作嵌入在 UIKit 中的 SwiftUI 视图?
您所需要的只是扔掉那个自定义主题,并使用标准@Published,如下所示
class CircleModel: ObservableObject {
@Published var text: String
init(text: String) {
self.text = text
}
}
Run Code Online (Sandbox Code Playgroud)
测试:Xcode 11.2 / iOS 13.2
| 归档时间: |
|
| 查看次数: |
2412 次 |
| 最近记录: |