[英]How do I trigger updateUIView of a UIViewRepresentable?
I'm trying to implement the uiView from SpritzSwift into a SwiftUI app, but after the first rendering I can't get it to update.我正在尝试将 SpritzSwift 中的uiView实现到 SwiftUI 应用程序中,但是在第一次渲染之后我无法更新它。 The manager that drives the UIView is working, but the UIView itself is not updating.
驱动 UIView 的管理器正在工作,但 UIView 本身没有更新。 I expected either that the UiView.setNeedsDisplay() inside the view controller or the changes in the @Bindable variables inside the wrapper would trigger updateUIView, but no dice.
我预计视图 controller 内的 UiView.setNeedsDisplay() 或包装器内的@Bindable 变量的更改会触发 updateUIView,但不会触发骰子。
No matter what change I make to the UiView or to its wrapper, it never gets updated (for example, the background never gets updated to clear color in the code example).无论我对 UiView 或其包装器进行什么更改,它都不会更新(例如,在代码示例中,背景永远不会更新为清除颜色)。 How do I get this view to update?
如何让这个视图更新?
Here's the SwiftUI Code:这是 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")
}
}
}
}
and here's the wrapper:这是包装:
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) {
}
}
You need to create UIKit view inside makeUIView
and via Binding pass only dependent data.您需要在
makeUIView
中创建 UIKit 视图,并通过绑定仅传递依赖数据。 That binding change, when related state - source of truth - changed, calls updateUIView
, where you should update your UIKit view.该绑定更改,当相关的 state - 事实来源 - 更改时,调用
updateUIView
,您应该在其中更新 UIKit 视图。
Here is simplified demo sketch only, to show concept (might have typos):这里只是简化的演示草图,以显示概念(可能有错别字):
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)
}
}
and button now should just change model data和按钮现在应该只更改 model 数据
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")
}
assuming updated properties假设更新的属性
@State private var currentWord = SpritzSwiftWord(word: "")
@State private var backgroundColor = UIColor.white // whatever you want
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.