After iOS 17 updated, if I enter a value or change Value in a text field and then go to the multitasking window or put the app in background mode and come back, the value is reset to its initial state. When the app goes into background mode or a multitasking window, does it call onAppear again to return the view to its initial state?

Is there any way to preserve input values in iOS17? This code was working fine on IOS 16.

struct RealSizeView: View {
    
    private enum Field: Hashable {
        case shoulder, chest, sleeve, length, waist, thigh, rise, hem, inseam
    }
    
    let realSizeType: RealSizeType

    @Binding var originalShoulder: Double
    @Binding var originalChest: Double
    @Binding var originalSleeve: Double
    @Binding var originalLength: Double
    
    @Binding var originalWaist: Double
    @Binding var originalThigh: Double
    @Binding var originalRise: Double
    @Binding var originalHem: Double
    @Binding var originalInseam: Double
    
    @State private var editedShoulder: Double = 0
    @State private var editedChest: Double = 0
    @State private var editedSleeve: Double = 0
    @State private var editedLength: Double = 0
    
    @State private var editedWaist: Double = 0
    @State private var editedThigh: Double = 0
    @State private var editedRise: Double = 0
    @State private var editedHem: Double = 0
    @State private var editedInseam: Double = 0

    @Environment(\.dismiss) private var dismiss
    
    var body: some View {
        NavigationStack {
            ZStack(alignment: .bottom) {
                Form {
                    Section {
                        switch realSizeType {
                        case .top:
                            topView
                        case .bottom:
                            bottomView
                        }
                    }
                }
            }
            .navigationTitle("Size")
            .onAppear {
                initValue()
            }
            
    private func initValue() {
        switch realSizeType {
        case .top:
            editedShoulder = originalShoulder
            editedChest = originalChest
            editedSleeve = originalSleeve
            editedLength = originalLength
        case .bottom:
            editedWaist = originalWaist
            editedThigh = originalThigh
            editedRise = originalRise
            editedHem = originalHem
            editedInseam = originalInseam
        }
    }
    
    @ViewBuilder
    var topView: some View {
        RealSizeInputRowView(title: Top.shoulder.name, amount: $editedShoulder, unit: unit)
            .focused($focusedField, equals: .shoulder)
            .onTapGesture { focusedField = .shoulder }
        RealSizeInputRowView(title: Top.chest.name, amount: $editedChest, unit: unit)
            .focused($focusedField, equals: .chest)
            .onTapGesture { focusedField = .chest }
        RealSizeInputRowView(title: Top.sleeve.name, amount: $editedSleeve, unit: unit)
            .focused($focusedField, equals: .sleeve)
            .onTapGesture { focusedField = .sleeve }
        RealSizeInputRowView(title: Top.length.name, amount: $editedLength, unit: unit)
            .focused($focusedField, equals: .length)
            .onTapGesture { focusedField = .length }
    }
    
    @ViewBuilder
    var bottomView: some View {
        RealSizeInputRowView(title: Bottom.waist.name, amount: $editedWaist, unit: unit)
            .focused($focusedField, equals: .waist)
            .onTapGesture { focusedField = .waist }
        RealSizeInputRowView(title: Bottom.thigh.name, amount: $editedThigh, unit: unit)
            .focused($focusedField, equals: .thigh)
            .onTapGesture { focusedField = .thigh }
        RealSizeInputRowView(title: Bottom.rise.name, amount: $editedRise, unit: unit)
            .focused($focusedField, equals: .rise)
            .onTapGesture { focusedField = .rise }
        RealSizeInputRowView(title: Bottom.hem.name, amount: $editedHem, unit: unit)
            .focused($focusedField, equals: .hem)
            .onTapGesture { focusedField = .hem }
        RealSizeInputRowView(title: Bottom.inseam.name, amount: $editedInseam, unit: unit)
            .focused($focusedField, equals: .inseam)
            .onTapGesture { focusedField = .inseam }
    }
1

There are 1 answers

0
JerryC On

Maybe you could use scenePhase to preserve the values? ScenePhase documentation. I remember it from Hacking With Swift that kept the timer running while the app went into the background.