在下面的代码中,变量“ yourVariable”在结构中定义。然后,我使用滑块更改“ yourVariable”,但是当我尝试在SecondView中使用该变量时,它使用的是原始变量,而不是更新的变量。有人告诉我我需要更新属性,我应该这样做吗?如果可以,请解释原因。
import SwiftUI
import PlaygroundSupport
struct MyVariables {
static var yourVariable = 500000.0
}
struct SecondView : View {
@Environment(\.presentationMode) var presentationMode
var string = MyVariables.yourVariable
var body: some View {
VStack {Button("\(string)") {
self.presentationMode.wrappedValue.dismiss()
}
}
}
}
struct ContentView : View {
@State private var showingSheet = false
@State public var step = 0
@State public var text = ""
@State public var slide = 20.0
@State public var slidetwo = MyVariables.yourVariable + 60000
var r0 : Double {
rvalues[(wearingMaskToggle ? 1:0) + (washingHandsToggle ? 2:0) + (quarantineToggle ? 8:0) + (coverMouthToggle ? 4:0)]
}
@State private var rvalues = [6.5, 6.1, 5.3, 4.8, 4.2, 3.5, 3.1, 2.9, 1.75, 1.5, 1.2, 1.0, 0.92, 0.82, 0.75, 0.7]
var body: some View {
ZStack {
Color.gray
.edgesIgnoringSafeArea(.all)
VStack {
HStack {
Button(action: {
if self.slidetwo > 10000{
self.slidetwo -= 1000 //When rand = 10050, it still works
}
}, label: {
Image(systemName: "minus")
})
Slider(value: $slidetwo, in: 10000...1000000, step: 1000)
.padding(20)
.accentColor(Color.green)
Button(action: {
if self.slidetwo < 1000000{
self.slidetwo += 1000
}
}, label: {
Image(systemName: "plus")
})
}.foregroundColor(Color.green) .padding(.horizontal, 100)
}
Text("Initial Population: \(Int(slidetwo))")
Button("Show Sheet") {
self.showingSheet.toggle()
}
.sheet(isPresented: $showingSheet) {
SecondView()
}
}
}
}
PlaygroundPage.current.setLiveView(ContentView())
答案 0 :(得分:1)
恐怕为时已晚,但是您也可以在代码中进行调整,就是将slideTwo变量更改为。
@Binding public var slidetwo: Double
您必须直接在结构中添加+60000,然后按如下所示初始化视图:
PlaygroundPage.current.setLiveView(ContentView(slidetwo: .init(get: { () -> Double in
return MyVariables.yourVariable
}, set: { (newValue) in
MyVariables.yourVariable = newValue
})))
这将导致将对slideTwo
的所有更改也应用到yourVariable
。但是,正如Pedro已经提到的那样,我不建议将这种方法与struct一起使用。
答案 1 :(得分:0)
首先,滑块将更新变量slidetwo
,其初始值为560000
。
打开第二个视图时,将结构的值存储到变量string
中,将始终具有yourVariable
定义的值,因此移动滑块不会影响所有第二个视图。
为了正确地执行此操作,如果希望在第二个视图内更改变量并在Binding
或简单的未初始化{中反映这些更改,可以使用ContentView
{1}}
使用第二个选项将导致将@State var
SecondView
中的var string = MyVariables.yourVariable
替换为
然后在工作表内的@State var string: String
中调用ContentView
而不是SecondView(string: String(slidetwo))
我不知道为什么在这里需要一个结构。它所做的只是保留一个默认值,仅此而已,并且您不会在任何地方更新该变量。您无法直接更新它,因为它无法绑定。
更新1:
根据您的评论,我了解到您希望将多个变量传递给SecondView,如果是这种情况,最好将SecondView()
与ObservableObject
结合使用
这很容易做到。首先创建一个包含所有变量的类。该类继承自EnvironmentObject
ObservableObject
现在在第一个视图上,您想要初始化该类并在需要的地方使用它。此时,幻灯片2不会更新class MyVariables: ObservableObject {
@Published var sliderTwo: Double = 0.0
@Published var yourVariable = 500000.0 // <- I don't know the purpose of this
init() {
sliderTwo = yourVariable + 60000 // <- This is the original value, in the original code
}
}
变量,而是模型中的变量,我们将需要像这样将@State
传递给第二个视图。
ObservedObject
现在,我们将模型和在第一个视图上更新的数据发送到第二个视图,所有更改都将反映在两个视图中,这只是最后一件事,请在第二个视图上捕获此struct ContentView: View {
@ObservedObject var model: MyVariables = MyVariables()
//@State public var slidetwo = MyVariables.yourVariable + 60000 <- no longer needed
// ... change every other reference of slidertwo to model.slidertwo
// except the following one witch instead of $slidertwo it will be $model.slidertwo
Slider(value: $model.slidertwo, in: 10000...1000000, step: 1000)
// ...
.sheet(isPresented: $showingSheet) {
SecondView().environmentObject(self.model) // send the model as an environment object
}
}
< / p>
EnvironmentObject
在这种情况下,struct SecondView: View {
// var string = MyVariables.yourVariable <- no longer needed
@EnvironmentObject var model: MyVariables
// ....
}
仍然没有改变,因为我们正在更新model.yourVariable
变量。
对模型所做的更改将反映在两个视图中。
根据我的经验,这是在SwiftUI中做事的正确方法