Recently I was building an app that lists public libraries in my home city. In early stages, the main view was just a list view that displays the library name and address. Something like this:
As you can see, some libraries don't have an address, because of some unrelated reasons. And if the address isn't present, the name should be vertically centred in the row.
A library not having an address is translated into my data model as an optional String. Here's a simplified version of my
If a library doesn't have an address, I won't render a
Text component for it, simple as that. And the easiest way for me to do that was using an
if let binding:
As it turns out, SwiftUI doesn't like this. The compiler tells us that
Closure containing control flow statement cannot be used with function builder 'ViewBuilder'. I beg your pardon?
How else am I supposed to conditionally render views in my app if "control flow statement cannot be used" to build it? After a moment of panic, I tested using a normal
And surprisingly that worked... wtf. Needless to say, I wasn't very exited with that solution, since it requires force unwrapping an optional value. I knew that there was another way.
One of the key features of SwiftUI is that if we add a
nil component to our view, it won't show up, it's just ignored. So, what's the easiest way to convert a conditional string into a conditional
Text? That's right, using
map over the possibly
nil address, without needing to force unwrap it, as the closure will only be executed if there was a value in the first place. This, however, seems like a hack. But hey, It works.
As I was reading some discussions about this issue, I found out that SwiftUI builds views using a struct named
ViewBuilder — remember the error I was getting before? If we peek its definition (
o in XCode to go to any class definition) we can clearly see that it supports
if statements, but nothing more.
SwiftUI is not event a year old, and we know Apple only introduces big features once a year. So here's hoping that when the next version of SwiftUI shows up, they add
if let support.