I'll answer the part that is related to Swift syntax, and then a little tangent about SwiftUI. However, it should not be treated as a signal/encouragement to post SwiftUI related question on this forum. Questions purely about SwiftUI should still be in Apple Dev's forum.
First, you need to notice that body
is a computed property, or specifically read-only computed property. It is signified by the syntax:
var propertyName: PropertyType {
// Function returning `Property Type`
}
with propertyName
being body
and PropertyType
being some View
. All in all, the thing inside bracket needs to return something of type some View
. You may not noticed it because you rarely write return
inside body
. This is because most of the time, it is a function with single statement, which is returned. That is, it is a function with implicit return. So when you write:
var body: some View {
VStack { ... }
}
Swift actually reads it as:
var body: some View {
return VStack { ... }
}
Now, if you have more than one statement, like in this case (findLocations
, and VStack
), Swift will no longer insert the return
for you. Making your function not returning anything, when it should return some View
, hence the error. The error is a little cryptic partly because you're using opaque type some View
, which requires you to return some value that conforms to View
.
So it's an error that you're not returning anything in a computed property. Doubly so in a computed property with opaque return type.
So, since you're doing some computation, then return the VStack
, what you need to do, is to add return
that Swift no longer insert for you (because you now have more than one statement).
var body: some View {
findLocation()
return VStack { ... }
}
All-in-all blindly flailing around in hope of fixing the compiler error won't get very far. You need to figure out what the error is saying, then figure out whether 1) you're not using the syntax the way it's meant to be used, 2) you're misunderstanding what the code means, or 3) you're not understanding the contract (computed property needs to return value).
Some rant about SwiftUI since the *fix* above still won't be enough.
Now, simply adding return
won't get it to work as expected because, remember, you do not mutate @State when computing body
. EVER. And right now, you're mutating detailArray
(a @State
) and coordArray
(another @State
) inside findLocations
, which is invoked within body
property. Bad, bad things all around.
You need to ask, "when do I mutate/update these values?". The answer is (almost) never "when the view is being drawn". Rather
- "when I first load up this view": for which you use
onAppear
, - "when something happens" like
onDrag
when user want to drag you item out for drag'n'drop,onTapGesture
when user is tapping your screen, etc.
Or in this case:
- "when a related data change": for which you'd pass it down from higher ups, and compute it together with the changed data.
Which is one thing you can do: whenever myLocations
changes, sneak in the code that update detailArray
and coordArray
in that, most likely you have enough room for three* . If it needs to be in the parent of the current view, just pass it down as a
let
variable.
* It's possible you want to cache the computation instead on recomputing it every time, which is a very non-trivial, if not advanced, technique.