为什么XUIView中的Binding<Bool>
看不到更新后的值?
我有一个SwiftUI XView
,它封装了一个XUIView
。在XUIView
中,我有一个Binding<Bool>
,它是用XView
的@Binding...
初始化的。在XUIView
中,我有一个UIButton
,我使用XUIView
中的“Binding”属性切换customFlag
。这很好地传播到SwiftUI视图中,因为Text
正确更新。但是,UIButton
的标题没有正确更新。XUIView._update
方法不会“看到”新值。
我错过了什么?我是否必须在updateUIView
方法中分配customFlag才能使其工作?
下面是一些print调用的示例代码,看看发生了什么:
import SwiftUI
struct UIKitBindingView: View {
@State private var customFlag: Bool = false
var body: some View {
VStack {
Text("customFlag: \(customFlag ? "ON" : "OFF")")
XView(customFlag: $customFlag)
.frame(width: 200, height: 100)
}
}
}
struct UIKitBindingView_Previews: PreviewProvider {
static var previews: some View {
UIKitBindingView()
}
}
struct XView: UIViewRepresentable {
typealias UIViewType = XUIView
typealias Context = UIViewRepresentableContext<XView>
@Binding var customFlag: Bool
init(customFlag: Binding<Bool>) {
self._customFlag = customFlag
}
func makeUIView(context: Context) -> XUIView {
Swift.print("XView: \(#function)")
let v = XUIView(frame: .zero, customFlag: $customFlag)
return v
}
func updateUIView(_ uiView: XUIView, context: Context) {
Swift.print("XView: \(#function)")
// uiView.customFlag = $customFlag
Swift.print("XView: \(#function): customFlag: \(customFlag) \n--\($customFlag)")
uiView._update()
}
}
class XUIView: UIView {
weak var button: UIButton?
var customFlag: Binding<Bool>
init(frame: CGRect, customFlag: Binding<Bool>) {
self.customFlag = customFlag
super.init(frame: frame)
Swift.print("XUIView: \(#function)")
_configure()
}
required init?(coder: NSCoder) {
self.customFlag = Binding(get: { true }, set: { v, t in })
super.init(coder: coder)
Swift.print("XUIView: \(#function)")
_configure()
}
deinit {
Swift.print("XUIView: \(#function)")
}
func _update() {
Swift.print("XUIView: \(#function): \(customFlag.wrappedValue)\n--\(customFlag)")
button?.setTitle("BUTTON:" + (customFlag.wrappedValue ? "ON" : "OFF"), for: .normal)
}
private func _configure() {
backgroundColor = .yellow
let b = UIButton()
button = b
self.addSubview(b)
b.translatesAutoresizingMaskIntoConstraints = false
let cons = [
self.centerXAnchor.constraint(equalTo: b.centerXAnchor),
self.centerYAnchor.constraint(equalTo: b.centerYAnchor),
]
NSLayoutConstraint.activate(cons)
b.setTitleColor(.systemBlue, for: .normal)
b.addAction(UIAction(handler: { action in
Swift.print("XUIView: \(#function): button action ***")
self.customFlag.wrappedValue.toggle()
}), for: .touchUpInside)
_update()
}
}
点击按钮后的控制台输出:
XUIView: __preview___configure(): button action ***
XView: __preview__updateUIView(_:context:)
XView: __preview__updateUIView(_:context:): customFlag: true
--Binding<Bool>(transaction: SwiftUI.Transaction(plist: []), location: SwiftUI.LocationBox<SwiftUI.Binding<Swift.Bool>.(unknown context at $10594f2e0).ScopedLocation>, _value: true)
XUIView: __preview___update(): false
--Binding<Bool>(transaction: SwiftUI.Transaction(plist: []), location: SwiftUI.LocationBox<SwiftUI.Binding<Swift.Bool>.(unknown context at $10594f2e0).ScopedLocation>, _value: false)
1条答案
按热度按时间qojgxg4l1#
不要调用XUIView的
_update()
(删除该方法),而是直接在updateUIView(_ uiView: XUIView, context: Context)
中进行更新: