I have a View, in which the user is able to enter some text into a TextField. I want to be able to get the text, which was entered in the TextField and use this value inside of a struct. The concept of the app, is that it shows the elevation degree of the sun. To be able to do this, it is scraping the values from a WebPage. However to make this app dynamic, the user has to be able to edit the url (you can change location, date etc in the url). I thought this would be fairly easy, since I only have to get some text, and edit a url before the url is being loaded. I have been able to pass the value into a view, however I need it in a struct. Maybe the whole "layout of my code is wrong, maybe I should get the data and draw the function in a view? I don't know. This is my first time coding with swift.
I want to change the latitude var.
This is my code:
View 1 (Input):
class ViewModel: ObservableObject {
@Published var latitude:String = ""
@Published var page = 0
}
struct ContentView: View {
@EnvironmentObject var value1: ViewModel
var body: some View {
if value1.page == 0{
VStack{
TextField("", text: $value1.latitude)
Button(action:{ value1.page = 1}){
Text("To next view")
}.frame(width: 300, height: 100, alignment: .center)
}
} else {
elevationGraph()
}
}
}
View 2 (Graph)
struct getHtml {
var url = URL(string: "https://midcdmz.nrel.gov/apps/spa.pl?syear=2020&smonth=1&sday=1&eyear=2020&emonth=1&eday=1&otype=0&step=60&stepunit=1&hr=12&min=0&sec=0&latitude=\(latitude)&longitude=10.757933&timezone=1.0&elev=53&press=835&temp=10&dut1=0.0&deltat=64.797&azmrot=180&slope=0&refract=0.5667&field=0")
func loadData(from url: URL?) -> String {
guard let url = url else {
return "nil"
}
let html = try! String(contentsOf: url, encoding: String.Encoding.utf8)
return html
}
}
struct elevationFunction: Shape {
var url: URL? //This only works in views, is there a way to do it in shape structs?
let html = getHtml.init().loadData(from: getHtml.init().url)
private func dbl1() -> Double {
let leftSideOfTheValue = "0:00:00,"
let rightSideOfTheValue = "\(month)/\(day)/\(year),1:00:00,"
guard let leftRange = html.range(of: leftSideOfTheValue) else {
print("cant find left range")
return 0
}
guard let rightRange = html.range(of: rightSideOfTheValue) else {
print("cant find right range")
return 0
}
let rangeOfTheValue = leftRange.upperBound..<rightRange.lowerBound
return Double(html[rangeOfTheValue].dropLast()) ?? 90
}
func path(in rect: CGRect) -> Path {
var path = Path()
path.move(to: CGPoint(x: 10, y: (125 - (90-dbl1()))))
path.addLine(to: CGPoint(x: 120, y: (125 - (90-45))))
path.addLine(to: CGPoint(x: 250, y: (125 - (90-dbl1()))))
var scale = (rect.height / 350) * (9/10)
var xOffset = (rect.width / 6)
var yOffset = (rect.height / 2)
return path.applying(CGAffineTransform(scaleX: scale, y: scale)).applying(CGAffineTransform(translationX: xOffset, y: yOffset))
}
}
struct elevationGraph: View {
var body: some View {
GeometryReader { geometry in
ZStack {
elevationFunction().stroke(LinearGradient(gradient: Gradient(colors: [Color.yellow, Color.red]), startPoint: .top , endPoint: .bottom), style: StrokeStyle(lineWidth: 6.0)).aspectRatio(contentMode: .fill)
}
.frame(width: 600, height: 800, alignment: .center)
}
}
}
elevationFunction(url: yourURL)(PS -- common practice is to always capitalize your data types; eg classes, structs) --ElevationFunction, or betterElevationShape- jnpdxvar url1: URL?int he second view, and passed it like you said, but now I get the error "Thread 1: EXC_BAD_ACCES (code=2, address=0x7ffee73ceff8)" on the line were I get the html'let html = getHtml.init().loadData(from: elevationFunction.init().url1)It doesn't show, before I run the program, but as soon, as I click next view, the program crashes and shows this error. - Rosenkrieg ykke