【问题标题】:UIViewRepresentable view not updating valueUIViewRepresentable 视图不更新值
【发布时间】:2020-09-17 12:44:03
【问题描述】:

我正在尝试创建自定义 SwiftUI 视图,但在通过 ObservedObject 更新值时遇到问题。

import SwiftUI
import Combine

struct ContentView: View {
    @ObservedObject var model:InfoViewModel = InfoViewModel()
    var body: some View {
        VStack(alignment: .leading){
            CustomView(value: self.model.title)
                .frame(width: 200, height: 200, alignment: .center)
        }
        .background(Color.green)
        .frame(minWidth: 0,
               maxWidth: .infinity,
               minHeight: 0,
               maxHeight: .infinity,
               alignment: .topLeading)
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

struct CustomView: UIViewRepresentable {
    typealias UIViewType = UIView
    var value:String
    var lblTitle:UILabel = UILabel()
    func makeUIView(context: Context) -> UIView {
        let view:UIView = UIView()
        view.addSubview(lblTitle)
        lblTitle.text = value
        lblTitle.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
        lblTitle.backgroundColor = UIColor.red
        lblTitle.textColor = UIColor.black
        return view
    }
    
    func updateUIView(_ uiView: UIView, context: Context) {
        self.lblTitle.text = value
        print("LBLTitle:\(self.lblTitle.text!)\nTitleValue:\(self.value)")
    }
}


class InfoViewModel: ObservableObject, Identifiable {
    @Published var title = "Title"
    private var count = 0
    init() {
        _ = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(fireTimer), userInfo: nil, repeats: true)
    }
    
    @objc func fireTimer() {
        count += 1
        
        self.title = "\(self.count)"
        print("Timer fired!\n\(self.title)")
    }
}

Project can be download from here

编辑: 我在@Asperi 回答后更改了代码,现在它正在更新值。但是正如 Dávid Pásztor 所建议的那样,在结构中创建 @ObservedObject 是不对的,那么我将如何通过创建 @ObservedObject 和 David 提供的链接将值传递给 CustomView 是旧的,并且该线程中的代码现在似乎不起作用。

这是正在运行的代码

struct CustomView: UIViewRepresentable {
    typealias UIViewType = UIView
    var value:String
    
    func makeUIView(context: Context) -> UIView {
        let view:UIView = UIView()
        let lblTitle:UILabel = UILabel()
        view.addSubview(lblTitle)
        lblTitle.text = value
        lblTitle.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
        lblTitle.backgroundColor = UIColor.red
        lblTitle.textColor = UIColor.black
        return view
    }
    
    func updateUIView(_ uiView: UIView, context: Context) {
        for view in uiView.subviews
        {
            if(view.isKind(of: UILabel.self))
            {
                (view as! UILabel).text = value
                print("LBLTitle:\((view as! UILabel).text!)\nTitleValue:\(self.value)")
            }
        }
        
        
    }
}

【问题讨论】:

  • 检查thisthis 答案。您不应该在View 中创建@ObservedObject。与您的问题无关,但不要在 SwiftUI 中使用 Timer.scheduledTimerselector。请改用其Combine 变体Timer.publish

标签: ios swift swiftui combine uiviewrepresentable


【解决方案1】:

您不需要将其保留为属性,因为 struct 可以重新创建(因此您松开它),而是可以通过参数中提供的方式访问您的视图。

注意:UIViewRepresentable 自己处理对相应视图的引用。

struct CustomView: UIViewRepresentable {
    typealias UIViewType = UILabel

    var value:String

    func makeUIView(context: Context) -> UILabel {
        let lblTitle = UILabel()
        lblTitle.text = value
        lblTitle.backgroundColor = UIColor.red
        lblTitle.textColor = UIColor.black
        return lblTitle
    }
    
    func updateUIView(_ uiLabel: UILabel, context: Context) {
        uiLabel.text = value
    }
}

【讨论】:

  • 如果我的自定义视图中有多个 UIView 怎么办?以及为什么它没有更新价值我没有得到它
  • 您可以在 Coordinator 中保留对所需视图的引用,它具有相同的生命周期。你的CustomView是struct,即value,它可以被复制创建多次,但是makeUIView被调用一次,而updateUIView只在最初创建的视图中被调用,所以它可能会丢失。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-09
  • 2019-12-20
  • 1970-01-01
相关资源
最近更新 更多