简体   繁体   English

SwiftUI:当分段选择器有新的 Position 时,视图不会刷新主体

[英]SwiftUI: The View doesn't refresh the Body when segmented Picker has a new Position

My App calculate for divers some important Values like max.我的应用程序为潜水员计算一些重要的值,例如最大值。 depth etc in meter or in feet.以米或英尺为单位的深度等。 The calculation is written in a separate File.计算被写在一个单独的文件中。 I have a Problem with the segmented Picker toggle.我对分段选择器切换有疑问。 If I launch the App the segmented Picker (Metric <-> Imperial) is on Metric.如果我启动应用程序,分段选择器(公制 <-> 英制)处于公制状态。 When I change the segmented Picker on Imperial nothing happened.当我更改 Imperial 上的分段选择器时,什么也没有发生。 But when I click on the Button and change the Value (32%, 33%) and push done the results stands in ft. .但是,当我单击按钮并更改值(32%、33%)并按下完成时,结果以英尺为单位。 When I change the segmented Picker Back to Metric nothing happened again.当我将分段的选择器改回公制时,什么也没有发生。 The View is only updated when I change the Value (32%, 33%, …), but I want that the Body refresh when the segmented Picker (Metric <-> Imperial) has a new "position".视图仅在我更改值(32%、33%、...)时更新,但我希望在分段选择器(公制 <-> 英制)具有新“位置”时刷新主体。

The App UI应用程序用户界面

在此处输入图像描述

在此处输入图像描述

   import SwiftUI
   import Combine

struct ContentView: View {
    
    @State var unitSelection = UserDefaults.standard.integer(forKey: "Picker")
    @State var O2_2 = 32
    @State var PO2_2 = 1.2
    
    var body: some View {
        ZStack {
            VStack {
                Picker("", selection: $unitSelection) {
                    Text("Metric").tag(0)
                    Text("Imperial").tag(1)
                }
                .pickerStyle(SegmentedPickerStyle()).padding(.horizontal, 89)
                .onReceive(Just(unitSelection)) {
                    UserDefaults.standard.set($0, forKey: "Picker")
                    switchMeasurement(measurement: $0)
                }
                Spacer()
            }
            BasicStructure(valueIndexO2Calculate_3: $O2_2, PO2_1: $PO2_2, unitSelection_1: unitSelection)
        }
    }
}

struct BasicStructure: View {
    //Variable from Picker: Calculate -> O2
    @Binding var valueIndexO2Calculate_3: Int
    @Binding var PO2_1: Double
     var unitSelection_1: Int
    
    var body: some View {
        VStack {
            HStack {
                Spacer()
            }
            Calculate(O2: $valueIndexO2Calculate_3, PO2: $PO2_1, unitSelection_2: unitSelection_1)
                
            ButtonMOD(valueIndexO2Calculate_2: self.$valueIndexO2Calculate_3, unitSelection_0: unitSelection_1)
            Spacer()
        }
    }
}

struct Calculate: View {
    @Binding var O2: Int
    @Binding var PO2: Double
    var unitSelection_2: Int
    
    var body: some View {
        VStack {
//O2 max. depth
            HStack (alignment: .center){
                VStack(alignment: .leading) {
                    Text("O2 max. depth")
                    Text("MOD O2")
                }
                Spacer()
                Text(calculateMod02(o2: self.O2, po2: Float(self.PO2)))
                    .padding(.trailing)
            }
                    .padding(.top).padding(.horizontal)
            Divider()
//eq. air depth
            HStack(alignment: .center) {
                VStack(alignment: .leading) {
                    Text("eq. air depth")
                    Text("EAD")
                }
                Spacer()
                Text(calculateEAD(o2: self.O2, po2: Float(self.PO2)))
                    .padding(.trailing)
            }
                    .padding(.horizontal)
            Divider()
//no deco time
            HStack(alignment: .center) {
                VStack(alignment: .leading) {
                    Text("no deco time")
                    Text("DECO 2000")
                }
                Spacer()
                Text("\(calculateDeco2000(o2: self.O2, po2: Float(self.PO2)), specifier: "%.0f")'")
                    .padding(.trailing)
            }
                    .padding(.horizontal)
            Divider()
//max. dive time
            HStack(alignment: .center) {
                VStack(alignment: .leading) {
                    Text("max. dive time")
                    Text("CNS")
                }
                Spacer()
                Text("\(calculateCNS(o2: self.O2, po2: Float(self.PO2)), specifier: "%.0f")'")
                    .padding(.trailing)
            }
                    .padding(.horizontal).padding(.bottom)
        }
        .padding()
    }
}

struct ButtonMOD: View {
    @State var showingDetail_O2 = false
    @State var showingDetail_PO2 = false
    //Variable from Picker: Calculate -> O2
    @Binding var valueIndexO2Calculate_2: Int
     var unitSelection_0: Int
    
    var body: some View {
    VStack {
        HStack(alignment: .center) {
            VStack(alignment: .leading) {
                Button(action: {
                    self.showingDetail_O2.toggle()
                }) {
                    Text("\(self.valueIndexO2Calculate_2)%")
                    Text("O2")
                    }.sheet(isPresented: $showingDetail_O2) {
                        SheetViewO2(showSheetView: self.$showingDetail_O2, valueIndexO2Calculate_1: self.$valueIndexO2Calculate_2, unitSelection_3: self.unitSelection_0)
                    }
            }
        }
        }.padding()
        .padding()
    }
}

struct SheetViewO2: View {
    @Binding var showSheetView: Bool
    //Variable from Picker: Calculate -> O2
    @Binding var valueIndexO2Calculate_1: Int
     var unitSelection_3: Int
    
    var body: some View {
        NavigationView {
            ValueO2(valueIndexO2Calculate_0: $valueIndexO2Calculate_1, unitSelection_4: unitSelection_3)
                .navigationBarTitle(Text("Select value"), displayMode: .inline)
                .navigationBarItems(trailing: Button(action: {
                    self.showSheetView = false
                }) {
                    Text("Done")
                        .bold()
            })
        }.navigationViewStyle(StackNavigationViewStyle())
    }
}

//Show "Picker O2"
struct ValueO2: View {
    //Variable from Picker: Calculate -> O2
    @Binding var valueIndexO2Calculate_0: Int
     var unitSelection_4: Int
    
    @State var valueArray : [Int] = []
    
    var body: some View {
        VStack{
            Section {
                Text("O2")
                Picker("",selection: $valueIndexO2Calculate_0) {
                    ForEach(valueArray, id: \.self){ value in
                        Text("\(value) %")
                    }
                }
            }
            .labelsHidden()
        }.onAppear{
            self.initPickerIndex()
        }
    }
           func initPickerIndex(){
               
               valueArray = []
               
               for index1 in 21..<50 {
                   valueArray.append(index1)
               }
                          
               for index2 in 1...5{
                   valueArray.append(40 + index2 * 10)
               }
           }
}

You don't need binding in this scenario, use direct value for BasicStructure and below (ie. similarly in subviews), like在这种情况下您不需要绑定,为BasicStructure及以下使用直接值(即在子视图中类似),例如

BasicStructure(valueIndexO2Calculate_3: $O2_2, PO2_1: $PO2_2, 
   unitSelection_1: unitSelection)   // << here !!

and

struct BasicStructure: View {
    //Variable from Picker: Calculate -> O2
    @Binding var valueIndexO2Calculate_3: Int
    @Binding var PO2_1: Double
    var unitSelection_1: Int        // << here !!

thus changing value in picker makes body refresh and dependent subviews rebuild.因此,在选择器中更改值会使主体刷新并重建相关的子视图。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM