I believe your issue is a result of using @State
variables to store all of the attributes. @State
variables are not consistent and get refreshed in the background by SwiftUI depending on your views visibility.
The piece that you are missing is a view controller class
stored in an @EnviornmentObject variable
. This class gets Initiated in your main contentView and is used to keep track and alter of all your attributes.
Each ContentView should reference the single @EnviornmentObject and pull data from that class.
Another solution which may work would be to replace all your @State variables with @StateObject
vars. @StateObject
vars are basically @State
vars but get initiated before the struct get loaded and the value is kept consistent regardless of the view state of the parent struct.
Here is a rough implementation of @EnvironmentObject within your project.
Basically use the @EnvironmentObject to pass values to child views
ContentView4.swift
struct ContentView4: View {
@EnvironmentObject cv4Controller: ContentView4Controller
var body: some View {
ScrollView(.vertical) {
ZStack{
VStack {
ForEach(0 ..< cv4Controller.dateien.count, id: .self) {
Button(action: {
print("button pressed")
x = x + 1
t = cv4Controller.dateien[x]
self.showingDetail.toggle()
}) {
Image("datei")
}
.scaledToFit()
.padding(0)
Text(self.dateien[$0])
Text(cv4Controller.t)
.foregroundColor(.white)
}
}
}
.sheet(isPresented:
cv4Controller.$showingDetail) {
ts(name: cv4Controller.t)
}
.onAppear { //# This `onAppear` is added to `ZStack{...}`
cv4Controller.doHttpRequest()
}
}
}
ContentView4Controller.swift
class ContentView4Controller: ObservableObject {
@Published var showingDetail = false
@Published var username: String = "."
@Published var password: String = "."
@Published private var name = String("Nikias2")
@Published private var t = String()
@Published private var x = -1
@Published private var t = String()
@Published private var x = -1
@Published var dateien = ["word.png"]
func doHttpRequest() {
let myUrl = URL(string: "http://192.168.1.180/int.php")! //# Trailing semicolon is not needed
var request = URLRequest(url: myUrl)
request.httpMethod = "POST"// Compose a query string
let postString = "Name=($username)&Passwort=($password)"
request.httpBody = postString.data(using: .utf8)
let task = URLSession.shared.dataTask(with: request) {
(data, response, error) in
//# Use if-let when you want to use the unwrapped value
if let error = error {
print("error=(error)")
return
}
//# Use guard-let when nil has no meaning and want to exit on nil
guard let response = response else {
print("Unexpected nil response")
return
}
// You can print out response object
print("response = (response)")
//Let's convert response sent from a server side script to a NSDictionary object:
do {
//# Use guard-let when nil has no meaning and want to exit on nil
guard let data = data else {
print("Unexpected nil data")
return
}
//#1 `mutableContainer` has no meaning in Swift
//#2 Use Swift Dictionary type instead of `NSDictionary`
let json = try JSONSerialization.jsonObject(with: data) as? [String: Any]
if let parseJSON = json {
// Now we can access value of First Name by its key
//# Use if-let when you want to use the unwrapped value
if let firstNameValue = parseJSON["Name"] as? String {
print("firstNameValue: (firstNameValue)")
let dateien = firstNameValue.components(separatedBy: ",")
print(dateien)
self.dateien = dateien
}
}
} catch {
print(error)
}
}
task.resume()
}
}
Example of main ContentView.swift
struct ContentView: View {
var cv4Controller: ContentView4Controller = ContentView4Controller()
var body: some view {
// your main page output
GeometryReader { geo in
// just a guess for what you have in your main contentView
switch(page) {
case .main:
ContentView2()
default:
ContentView4()
break
}
}.environmentObject(cv4Controller) // this will make cv4Controller available to all child view structs
}
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…