Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/102.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 如何更新嵌入到UIKit中的SwiftUI视图?_Ios_Swift_Uikit_Swiftui - Fatal编程技术网

Ios 如何更新嵌入到UIKit中的SwiftUI视图?

Ios 如何更新嵌入到UIKit中的SwiftUI视图?,ios,swift,uikit,swiftui,Ios,Swift,Uikit,Swiftui,我正在寻找一个等效于AppKit的UIKit,这样我就可以在UIKit中嵌入一个SwiftUI视图。不幸的是,UIKit没有与NSHostingView等效的类。我们所拥有的最接近的,相当于,命名为。因为视图控制器包含一个视图,所以我们应该能够,然后抓取视图并直接使用它 这说明这是在UIKit中嵌入SwiftUI视图的方法。然而,它们通常无法解释如何从UIKit进行通信➡️ 快捷键。例如,假设我实现了一个充当进度条的SwiftUI视图,我希望定期更新进度。我希望我的遗留/UIKit代码更新Swi

我正在寻找一个等效于AppKit的UIKit,这样我就可以在UIKit中嵌入一个SwiftUI视图。不幸的是,UIKit没有与
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
    中)
  • ❌ <代码>文本(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
        }
    }
    

    测试日期:Xcode 11.2/iOS 13.2

    您的信息已过期
    ObservableObject
    已更改(而iOS 13.0仍处于测试阶段),要求使用
    objectWillChange
    发布者,而不是
    didChange
    发布者。Asperi的回答显示了一种更简单的方法来实现您的
    可观察对象
    ,方法是让它从其
    @已发布的
    属性中合成自己的发布者。