Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
3.5k views
in Technique[技术] by (71.8m points)

ios - What's the best way in SwiftUI to handle fields in a SubView within a TabViews

I'm currently struggling with my SwiftUI app due to bugs in IOS14.3.

I have my data in an environmental object and normally I would populate e.g. textfields via the onAppear function and @State variables of views. However in the new feature I'd like to use a tabview and here the onAppear / onDisappear functions go crazy as described e.g. here: SwiftUI PageTabView in iOS14.2 will Recall ChildView onAppear method Many times in the current IOS version.

I've thought of a workaround and tried to use the variables from the environmental object directly in the textfield but that's not compatible with my dynamic array as I get an index out of range error when I delete the entries.

Therefore I would be very grateful if anyone of you has a suggestion on how I could handle:

  1. The population / saving of the changes once the user swipes to the next view
  2. How to avoid the index out of range issue

Is there a better way on how to do it than I've done it currently? It somehow doesn't feel like the easies way.

Here's my code:

Model

struct Example: Codable {
    var id: String = UUID().uuidString
    var name: String
}

ViewModel

class DBhandler: ObservableObject {
    @Published var examples: [Example] = [Example(name: "Test1"), Example(name: "Test2")]
}

View

struct ContentView: View {
    @EnvironmentObject var dbhandler: DBhandler
    @State var selectedTab : Int = 0
    var body: some View {
        VStack{
            TabView(selection: $selectedTab){
                ForEach(dbhandler.examples.indices, id: .self) {exampleIndex in
                    SubView(exampleIndex: exampleIndex).tag(exampleIndex)
                }
            }
            .tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
        }
    }
}

struct SubView: View {
    @EnvironmentObject var dbhandler: DBhandler
    @State private var inputText : String = ""
    let exampleIndex : Int
    var body: some View {
        //If uncommented it just hides the Index out of range error which occurs anyway
        //        if exampleIndex < dbhandler.examples.count {
        VStack{
            Text(dbhandler.examples[exampleIndex].name)
            //Option 1
            TextField(inputText, text: $inputText)
            //Option 2
            TextField(dbhandler.examples[exampleIndex].name, text: $dbhandler.examples[exampleIndex].name)
            
            Button(action: {
                dbhandler.examples.remove(at: exampleIndex)
            }, label: {
                Text("Delete entry: (dbhandler.examples[exampleIndex].name)")
            })
        }
        .onAppear(perform: {
            print("On Appear called")
            //Get data
            inputText = dbhandler.examples[exampleIndex].name
        })
        .onDisappear(perform: {
            print("On Disappear called")
            //Save data
            dbhandler.examples[exampleIndex].name = inputText
        })
        //        }
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
等待大神解答

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...