Swift UI — iOS Designing up a notch

Hello folks, as we all know it’s been some time now since SwiftUI was launched by Apple in WWDC 2019. Also it’s becoming mature in its components and stability with every release. So whats all the hype about ? How its better than our long lived friend UIKit. Let’s check out.

Problem with Traditional UIKit

IBOutlets : When iOS developers started with UIKit, xib and Xcode were two different applications. Later Apple merged it with Xcode, so may be thats the reason we still get IBOutlet connectivity issues. Whenever user deletes an IBOutlet variable your application crashes if the connection isn’t removed manually from Xib.

Storyboard : As iOS developers we have always faced the issues around handling massive storyboards . Initially when we start adding screen in storyboard it really looks good. But as we are an year or more in the same storyboard, what we have is a storyboard monster. It’s very difficult to maintain and makes heavy to build the app.

Xib/Storyboard maintenance cost : With storyboard and Xib comes the responsibility to manage the UI across team when it comes to merging them. Storyboard/Xib conflicts are nightmare for any developer. You get stuck in all those xml tags and constraints .

Auto-layout : Constraint based layout has its own handling issues. One constraint missed while adding a view and all elements can get messed up. You can end up clearing and setting all constraints again.

The release of iOS 13 brought a way out for us from these issues, SwiftUI.

SwiftUI to the rescue !

“Swift UI is a UI development framework which is declarative, user friendly and works with much lesser code.”

SwiftUI is out answer to all those UIKit issues mentioned above. Swift Ui syntax is also easy to understand , so its a must go for beginners to dive in iOS UI development. Swift UI gives us realtime preview of whats being written in code, so we don’t need to run application every time to view changes in simulator (so no need to worry about heavy compile & build time like storyboard). The SwiftUI APIs are consistent across platforms, so it will be easier to develop the same-ish app on multiple platforms using the same source code on each(no worry of tricky constraints). SwiftUI is design is nothing but instructions passed in a declarative way(so no mess-up in merge conflicts).

You can now drag drop more than before. viz. the borders, corner radius, aspect ratio etc. Also Swift UI comes with default dark mode support. It handles the basic colour changes to let your screen adapt to dark mode .

Swift UI has a big advantage that it’s compatible with existing code bases. You can start designing with Swift UI in an existing application which has storyboard/xibs for old screens. UIViewControllerRepresentable is used to UIViewController object inside the Swift UI. Similarly to use Swift UI View in UIViewController a UIHostingController is used.

Swift UI uses relatively very lesser code as compared to swift and objective c. I’ll show how less actually I mean . First let’s also clear that what do I mean when I say Swift Ui is declarative. SwiftUI uses a declarative syntax so you can simply state what your user interface should do. For example, you can write that you want a list of items consisting of Text, descriptionText then image , then describe font, padding, aspect ratio as needed. Your code is simpler and easier to read than ever before, saving you time and maintenance.

By default, SwiftUI view files declare two structures.

  1. The first structure conforms to the View protocol and describes the view’s content and layout. var body: some View defines a new computed property called body, which has an interesting type: some View. This means it will return something that conforms to the View protocol, but that extra some keyword adds an important restriction: it must always be the same kind of view being returned. You can’t sometimes return one type of thing and other times return a different type of thing. The View protocol has a requirement, that you have a computed property called body that returns some View .
  2. The second structure declares a preview for that view. This isn’t a part of code that is shipped to Appstore. This struct conforms to PreviewProvider . A preview provider provides up with the live preview that is available on right side in Xcode with SwiftUI view. To preview & interact with views from the canvas in Xcode, and to use all the latest features ,your Mac should be running macOS Big Sur.
import SwiftUI

struct ContentView: View {
    
    let avengers : [Hero] = [
        Hero( name: "Iron Man", description: "Genius, billionare, play***, philanthropist", color: .red, images: ["iron_1","iron_2","iron_3","iron_4","iron_5","iron_6"]),
        Hero( name: "Captain America", description: "Avengers Assemble!", color: .blue, images: ["captain_1","captain_2","captain_3","captain_4","captain_5"]),
        Hero( name: "Wanda", description: "Everybody's afraid of something", color: .blue, images: ["wanda_1","wanda_2","wanda_3","wanda_4"]),
        Hero( name: "Vision", description: "Our very strength invites challenge, challenges incite conflicts, and conflicts breeds catastrophe", color: .blue, images: ["vision_1","vision_2","vision_3","vision_4"]),
        Hero( name: "Hulk", description: "Thats my secret, I am always angry", color: .blue, images: ["hulk_1","hulk_2","hulk_3","hulk_4"])
    ]
    
    let images = ["iron_1","iron_2","iron_3","iron_4","iron_5","iron_6"]
    
private var gridItemLayout = [GridItem(.flexible())]
        
var body:  some View
{
        
        List(avengers) { hero in
            
    GeometryReader { geometry in
        VStack(alignment : .leading){
            
            Text(hero.name)
                .font(.title)
                    .padding(.leading)
                .offset(x: 0, y: 0)
                .frame(width: geometry.size.width , height: 25, alignment: .leading)
            
            Text(hero.description)
                .font(.subheadline)
                .padding([ .leading])
                .frame(width: geometry.size.width  , height: 40, alignment: .leading)
            
            ScrollView(.horizontal,showsIndicators: false) {
                LazyHGrid(rows: gridItemLayout, spacing: 20) {

                    ForEach(hero.images, id: \.self) { imageName in
                        
                            Image(imageName)
                            .resizable()
                            .aspectRatio(contentMode: .fill)
                            .frame(width: 100, height: 100, alignment: .center)
                                .cornerRadius(8)
                    }
                }
            }
            .offset(x: 0, y: 0)
            .frame(minWidth: 0, idealWidth: /*@START_MENU_TOKEN@*/100/*@END_MENU_TOKEN@*/, maxWidth: /*@START_MENU_TOKEN@*/.infinity/*@END_MENU_TOKEN@*/, minHeight: /*@START_MENU_TOKEN@*/0/*@END_MENU_TOKEN@*/, idealHeight: /*@START_MENU_TOKEN@*/100/*@END_MENU_TOKEN@*/, maxHeight: 100, alignment: .center)
            
        }
    }
        }.environment(\.defaultMinListRowHeight, 200)
}

}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

struct Hero: Identifiable {
    
    var id = UUID()
    var name : String
    var description: String
    var color: Color
    var images : [String]
    
}

When you are writing code in SwiftUI you may see an error at top right stating “automatic preview updating is paused.” You simply need to to click resume button next to it and wait for preview to load the updates. If you don’t see the Resume button, click the editor options button, and select Editor and Canvas:

In above example we can see how a small code (line 27–65) we wrote to add a horizontal HGrid(UICollectionview in UIKit) inside a List(UITableView in UIKit).

To achieve the same in UIKit designing we would have needed to write all those big delegate methods, create IBOutLet connections and write code for reuse cells . Also you and your colleague can work now on same View and merge hassle free, since it’s just a piece of code drawing your view.

The preview provider part in above code work to provide you the real-time preview for the code you write. We have passed a hardcoded array to List which uses some images stored in the assets folder. The struct Hero conforms to Identifiable protocol which is needed to identify each object in an array uniquely(by generating a default id) when passed to a List. Geometry reader helps us to get the sizes and frames of the drawn view and elements in its own coordinate space.

The only disadvantage as of now for SwiftUI is that it needs iOS 13 as a minimum deployment target which many of the customer and users won’t agree with . But it’s surely the future of UI development in iOS. Dealing with SwiftUI variables and data processing is another area which I didn’t dive in for this context, but you should definitely start playing with the UI elements and designing.

Hope this helps you to get a glimpse of the power of SwiftUI and you start cruising on this new ride. Happy coding!!

One thought on “Swift UI — iOS Designing up a notch

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.