SwiftUI is really easy and fast for prototyping UI. This opinion has been expressed by many developers in different wordings. Recently, SwiftLee expressed the same in Twitter.
Antoine v.d. SwiftLee 🚀@twannl
@pradeepb28 Yes, absolutely! Makes it so easy to build UIs!11:24 AM - 01 Nov 2020
I've seen such comments about SwiftUI but this time I decided to add a response, because of the recent challenges (maybe call them limitations 🤔) I've faced with implementing some not views in SwiftUI.
@twannl @pradeepb28 SwiftUI is so easy when you are building simple and native views. Complex views in SwiftUI a nightmare.
Also adding functionality to existing primitive views seems to be hard.13:28 PM - 01 Nov 2020
So, how does SwiftUI fare against the complex requirements of a real world project? At present, it has been in production for only just over a year and we can't find many SwiftUI apps in the App Stores.
But if there is any good time to build and ship SwiftUI apps, it is right now!
Disclaimer: Continue only if your minimum target is iOS 13.
Even though most of the SwiftUI features which make it production ready have shipped only with iOS 14, you can build a decent app for iOS 13 which becomes exceptional when the user updates.
Take the common requirement of a collection view in many apps. You can use the new lazy grids for iOS 14 and drop down to a combination of VStack
and HStack
as Paul explains in this article for iOS 13. Also if your requirement can just be fulfilled using a list, then go for it in iOS 13.
But if your requirements are complex or you want to tweak the default behavior a little bit, you might find it difficult. Today we'll tackle one such scenario where I want some tweaks to the default behavior and over the coming weeks we'll see many more.
SidebarListStyle
introduced this year, makes it so easy to get the default Sidebar behavior in your app.
struct SidebarList: View {
@State var selected: Int? = nil
var body: some View {
NavigationView {
List(0...10, id: \.self, selection: $selected) { number in
NavigationLink(destination: Text("\(number) is selected"), label: { Text("Select \(number)")})
}
.listStyle(SidebarListStyle())
Text("Nothing is selected")
}
}
}
Just with that few lines, you get the default behavior of the Sidebar in a nice Master Detail layout.
You get a lot of things out of the box. A Sidebar with spaced out list items, no separators, a nice indication for the selection, a button to toggle the visibility of the Sidebar. If you use the new Label
for the list item, the images will be in the accentColor
. So cool, with just a few lines of code!
Now my requirement is to have Sidebar and the detail view, but I don't want them to be inside a NavigationView
. Sounds simple right? Lets try.
struct SplitView: View {
@State var selected: Int? = nil
var body: some View {
HStack {
List(0...10, id: \.self, selection: $selected) { number in
Text("Select \(number)")
}
.listStyle(SidebarListStyle())
detailView
}
}
@ViewBuilder var detailView: some View {
if selected == nil {
Text("Nothing is selected")
} else {
Text("\(selected!) is selected")
}
}
}
This is not what I expected to see from the above code. But SwiftUI views react to the environment, you can say, SwiftUI views are dependent on the environment. We got the spaced out list items without separator, but no selection and hence no highlighting when tapped and we need to frame the views in required size.
I have no clue why removing the NavigationLink
stops the List
selection from working. You can get it to work by adding an onTapGesture
to the Text
. The selection
parameter in the list in no longer required. You can fix the Sidebar width by using the frame
modifier.
List(0...10, id: \.self, selection: $selected) { number in
Text("Select \(number)")
.onTapGesture {
selected = number
}
}
.frame(width: 200)
Again, this is not what I expected but SwiftUI did its job perfectly. We can fix this easily by adding a Spacer()
before and after detailView
.
The functionality is working properly, so you can tap any item to select it. But there is not visual indication of which item is currently selected. To highlight the selection, add a background
with `accentCol
Here's the final output.
And, below is the code to get that output. Here's the [gist].(https://gist.github.com/mimthath4/4f37773f1f471bdf767ae151685414d3)
We've used a HStack
and contentShape
modifier so that tapping anywhere on the list item enables selection.
This is not the perfect solution, but this works. It took me some mental preparation to share working solutions publicly rather than waiting for the perfect solution all the time.
If you want to see this solution in Production, checkout Swimbols on the App Store.
Follow me on Twitter, so that I'll let you when I write more. Feel free to DM if you want to ask/share something.
Top comments (0)