我觉得我缺少一些非常基本的东西,但是当单击按钮时,这个示例 SwiftUI 代码不会修改视图(尽管绑定更新)
我读过的教程表明这是使用绑定的正确方法,视图应该自动刷新
import SwiftUI
struct ContentView: View {
@Binding var isSelected: Bool
var body: some View {
Button(action: {
self.isSelected.toggle()
}) {
Text(isSelected ? "Selected" : "Not Selected")
}
}
}
struct ContentView_Previews: PreviewProvider {
@State static var selected: Bool = false
static var previews: some View {
ContentView(isSelected: $selected)
}
}
Run Code Online (Sandbox Code Playgroud)
E.C*_*oms 12
在 SwiftUI 的顶层,@Binding 无法刷新 View 层次结构,除非手动添加 @state 或其他刷新触发器。
struct ContentView: View {
@Binding var isSelected : Bool
@State var hiddenTrigger = false
var body: some View {
VStack {
Text("\(hiddenTrigger ? "" : "")")
Button(action: {
self.isSelected.toggle()
self.hiddenTrigger = self.isSelected
}) {
Text(self.isSelected? "Selected" : "not Selected")
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var selected: Bool = false
static var previews: some View {
ContentView(isSelected: Binding<Bool>(get: {selected}, set: { newValue in
selected = newValue}))
}
}
Run Code Online (Sandbox Code Playgroud)
rag*_*ius 10
你没有误解任何东西。使用@Binding 的视图将在底层@State 更改时更新,但@State 必须在视图层次结构中定义。(否则你可以绑定到发布者)
下面,我将 ContentView 的名称更改为 OriginalContentView,然后在包含原始内容视图的新 ContentView 中定义了 @State。
import SwiftUI
struct OriginalContentView: View {
@Binding var isSelected: Bool
var body: some View {
Button(action: {
self.isSelected.toggle()
}) {
Text(isSelected ? "Selected" : "Not Selected")
}
}
}
struct ContentView: View {
@State private var selected = false
var body: some View {
OriginalContentView(isSelected: $selected)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Run Code Online (Sandbox Code Playgroud)
小智 7
SwiftUI 视图会影响@Binding. @State影响 SwiftUI 视图。
@Statevar 影响视图,但要影响另一个视图,@State它必须通过添加前导$值名称来用作绑定,并且它只能在 SwiftUI 中工作。
要从外部触发 SwiftUI 更改,即交付/更新图像,请使用如下所示的 Publisher:
// Declare publisher in Swift (outside SwiftUI).
public let imagePublisher = PassthroughSubject<Image, Never>()
// It must be handled within SwiftUI.
struct ContentView: View {
// Declare a @State that updates View.
@State var image: Image = Image(systemName: "photo")
var body: some View {
// Use @State image declaration
// and subscribe this value to publisher "imagePublisher".
image.onReceive(imagePublisher, perform: { (output: Image) in
self.image = output // Whenever publisher sends new value, old one to be replaced
})
}
}
// And this is how to send value to update SwiftUI from Swift:
imagePublisher.send(Image(systemName: "photo"))
Run Code Online (Sandbox Code Playgroud)
进一步研究这个问题,我想我明白发生了什么。
@Binding在这种情况下,我想在构建自定义控件时使用(例如 SwiftUI 的 native Toggle,它也绑定到 a Bool)
问题是,当状态更改时ContentView_Previews,(即 line @State static var selected: Bool = false)中的静态状态不会触发预览的重新渲染,因此即使所选状态由于与控件交互而发生了更改,控件(ContentView_Previews) 不重新渲染自身
这使得在 SwiftUI 预览中单独测试控件变得很困难,但是将状态移动到虚拟ObservableObject实例中可以正常工作。这是代码:
import SwiftUI
import Combine
class SomeData: ObservableObject {
@Published var isOn: Bool = false
}
struct MyButton: View {
@Binding var isSelected: Bool
var body: some View {
Button(action: {
self.isSelected.toggle()
}) {
Text(isSelected ? "Selected" : "Not Selected")
}
}
}
struct ContentView: View {
@EnvironmentObject var data: SomeData
var body: some View {
MyButton(isSelected: $data.isOn)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView().environmentObject(SomeData())
}
}
Run Code Online (Sandbox Code Playgroud)
似乎更改@State static var不会触发预览重新渲染。在上面的代码中,我的@Binding示例被移入MyButton,内容视图的虚拟环境实例绑定到其isSelected属性。点击按钮会按照 SwiftUI 预览中的预期更新视图。
| 归档时间: |
|
| 查看次数: |
14983 次 |
| 最近记录: |