【问题标题】:How do I trigger updateUIView of a UIViewRepresentable?如何触发 UIViewRepresentable 的 updateUIView?
【发布时间】:2021-04-04 06:35:39
【问题描述】:

我正在尝试将 SpritzSwift 中的 uiView 实现到 SwiftUI 应用程序中,但在第一次渲染后我无法更新它。驱动 UIView 的管理器正在工作,但 UIView 本身没有更新。我预计视图控制器内的 UiView.setNeedsDisplay() 或包装器内 @Bindable 变量的更改会触发 updateUIView,但不会触发。

无论我对 UiView 或其包装器进行什么更改,它都不会更新(例如,在代码示例中,背景不会更新以清除颜色)。如何更新此视图?

这是 SwiftUI 代码:

import SwiftUI
struct Content: View {

    @State public var ssManager:SpritzSwiftManager = SpritzSwiftManager(withText: "", andWordPerMinute: Int(200))
    @State public var ssView:SpritzSwiftView = SpritzSwiftView(frame: CGRect(x: 0, y: 0, width: 200, height: 600 ))
    @State private var currentWord = ""
    
    var body: some View {
        VStack {
            Text("SpritzTest")
                .padding()
            let spritzUIView = SpritzUIViewRepresentable(SpritzView: $ssView,SpritzViewManager:$ssManager, CurrentWord: $currentWord)
            spritzUIView.padding()
            Button(action:
                    {
                        ssManager  = SpritzSwiftManager(withText: "Text try one two three", andWordPerMinute: 200)
                        spritzUIView.SpritzView = SpritzSwiftView(frame: CGRect(x: 0, y: 0, width: 200, height: 40 ))
                        spritzUIView.SpritzView.backgroundColor = .clear
                        ssManager.startReading { (word, finished) in
                            if !finished {
                                self.ssView.updateWord(word!)
                                currentWord = word!.word
                                spritzUIView.CurrentWord = currentWord

                            }
                        }
                    })
            {
                Text("Start")
            }
        }
    }
}

这是包装器:

struct SpritzUIViewRepresentable : UIViewRepresentable{
    @Binding var SpritzView:SpritzSwiftView
    @Binding var SpritzViewManager:SpritzSwiftManager
    @Binding var CurrentWord:String
    
    func makeUIView(context: Context) -> SpritzSwiftView {
           return SpritzView
       }
       func updateUIView(_ uiView: SpritzSwiftView, context: Context) {
       }
}

【问题讨论】:

    标签: swift swiftui


    【解决方案1】:

    您需要在makeUIView 中创建 UIKit 视图,并通过绑定仅传递相关数据。当相关状态 - 事实来源 - 发生变化时,该绑定更改调用updateUIView,您应该在其中更新您的 UIKit 视图。

    这里只是简化的演示草图,用于展示概念(可能有错别字):

    struct SpritzUIViewRepresentable : UIViewRepresentable{
        @Binding var currentWord: SpritzSwiftWord
        @Binding var backgroundColor: UIColor
        
        func makeUIView(context: Context) -> SpritzSwiftView {
            // create and configure view here
            return SpritzSwiftView(frame: CGRect.zero) // frame does not matter here
        }
    
        func updateUIView(_ uiView: SpritzSwiftView, context: Context) {
           // update view properties here from bound external data
           uiView.backgroundColor = backgroundColor
           uiView.updateWord(currentWord)
        }
    }
    

    按钮现在应该只更改模型数据

        VStack {
            Text("SpritzTest")
                .padding()
            SpritzUIViewRepresentable(backgroundColor: $backgroundColor, SpritzViewManager:$ssManager, currentWord: $currentWord)
               .padding()
            Button(action:
                {
                    ssManager  = SpritzSwiftManager(withText: "Text try one two three", andWordPerMinute: 200)
    
                    self.backgroundColor = .clear
                    ssManager.startReading { (word, finished) in
                        if !finished {
                            self.currentWord = word
                        }
                    }
                })
            {
               Text("Start")
            }
    

    假设更新的属性

    @State private var currentWord = SpritzSwiftWord(word: "")
    @State private var backgroundColor = UIColor.white         // whatever you want
    

    【讨论】:

    • 完美!这很好用。我现在更好地理解了这是如何工作的。从文档中根本不清楚 updateUIView 应该包含绑定数据,我希望这个答案对将来的人有所帮助。
    猜你喜欢
    • 2022-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-19
    • 1970-01-01
    • 1970-01-01
    • 2019-12-20
    相关资源
    最近更新 更多