Skip to content

Latest commit

 

History

History

BeginnersViews

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 

A Beginners Guide to Views in SwiftUI

Understand this

A view in SwiftUI is a lightweight, transient object designed to be thrown away when the source for it is changed.

Unlike views in UIKit, SwiftUI views are not intended to be permanent or manually updated and instead of recomputed dynamically whenever the underlying data changes.

Views as Value Types

Views in SwiftUI are all struct, which means they are value types. 

These views have advantages:

  • struct are lightweight and performant
  • Views are immutable making them predictable and easy to reason about

The View Protocol

All SwiftUI views conform to the View protocol which requires a single computed body property that describes the view's content.

Here is a minimal example of a SwiftUI view:

struct MyView: View {
    var body: some View {
        Text("Hello, SwiftUI!")
            .padding()
    }
}

Note that the view is composed of another view ( Text("Hello, SwiftUI!") is another view)

The Data-Driven Paradigm

SwiftUI views use a data-driven paradigm meaning that the views are driven by the data that backs them.

Ultimately this simplifies the UI updates significantly as it isn't necessary to manually refresh, reload or redraw views. The process is simpler since once the data is updated SwiftUI takes care of the view updates.

struct CounterView: View {
    @State private var count = 0

    var body: some View {
        VStack {
            Text("Count: \(count)")
                .font(.largeTitle)

            Button("Increment") {
                count += 1
            }
        }
        .padding()
        .frame(maxWidth: .infinity, maxHeight: .infinity)
    }
}

Lifecycle

SwiftUI provides us .onAppear() and .onDisappear() modifiers.

.onAppear() This instance method adds an action to perform before the view appears. Therefore we can think of this as roughly analogous to UIKit's viewWillAppear function.

.onDisappear() This instance method adds an action to perform after the view disappears. Therefore we can think of this as roughly analogous to UIKit's viewDidDisappear function.

Modifiers and lifecycle methods Modifiers can also be used to hook into the view lifecycle. For instance, the .onAppear() and .onDisappear() modifiers allow you to execute code when a view appears or disappears, respectively.

Text("Hello, World!")
    .onAppear {
        print("The view has appeared")
    }
    .onDisappear {
        print("The view has disappeared")
    }

So in this code onAppear and onDisappear are both modifiers.

Article: https://stevenpcurtis.medium.com/the-swiftui-view-lifecycle-c3630ca2b833

State Management

SwiftUI offers tools to manage state, ensuring views stay in sync with the data that drives them.

Common property wrappers

@State For local, mutable state within a view. @Binding For passing state between views. @Environment and @EnvironmentObject For managing shared app-wide data. Article: https://medium.com/@stevenpcurtis/swiftuis-state-management-f6422c5731e9

Composability

A simple example

If we create a simple screen to represent a user profile that is split into three components, ProfileImageView, ProfileNameView, and ProfileBioView, which is then combined in a ProfileView.

import SwiftUI

struct ProfileView: View {
    var body: some View {
        VStack(spacing: 20) {
            ProfileImageView(imageName: "profile_image")
            ProfileNameView(name: "John Doe")
            ProfileBioView(bio: "iOS Developer passionate about creating innovative solutions.")
        }
        .padding()
    }
}

struct ProfileImageView: View {
    var imageName: String
    
    var body: some View {
        Image(imageName)
            .resizable()
            .scaledToFit()
            .frame(width: 100, height: 100)
            .clipShape(Circle())
            .shadow(radius: 5)
    }
}

struct ProfileNameView: View {
    var name: String
    
    var body: some View {
        Text(name)
            .font(.title)
            .fontWeight(.bold)
    }
}

struct ProfileBioView: View {
    var bio: String
    
    var body: some View {
        Text(bio)
            .font(.body)
            .foregroundColor(.gray)
            .multilineTextAlignment(.center)
    }
}

Each component is responsible for one specific part of the UI, and ProfileView simply combines them. This approach makes the code modular and easy to manage.

Article: https://medium.com/@stevenpcurtis/view-composition-in-swiftui-9386625b243c

Best Practices

Think in Terms of Data Flow Focus on how data flows through your app rather than manually managing views.

Decompose Complex UIs Break down large views into smaller, reusable components for better maintainability.

Conclusion

SwiftUI views represent a modern, efficient, and intuitive way to build user interfaces. Their transient, data-driven nature allows developers to focus on what their app should display rather than how to update it. By embracing SwiftUI's declarative approach, you can write more concise, readable, and maintainable code while letting the framework handle the complexities of view management.