Splitting SwiftUI into Components: A Modular Approach to Building iOS Apps

One effective strategy is to split your SwiftUI views into smaller, reusable components. This modular approach promotes cleaner, more maintainable code and enhances reusability across your app. In this blog post, we’ll explore how to decompose a SwiftUI view into smaller components with a practical example.

The Benefits of Component-Based Design

Before diving into the code, let’s discuss why you should consider splitting your SwiftUI views into components:

  1. Reusability: By creating smaller components, you can reuse them across different parts of your app, reducing redundancy and improving consistency.
  2. Readability: Smaller, well-named components make your code easier to read and understand, which is particularly beneficial when working in teams.
  3. Maintainability: Isolating different parts of your UI into components makes it easier to manage and update them independently, reducing the risk of introducing bugs.

Example: Breaking Down a User Profile View

Let's start with a basic example of a user profile view and then break it down into components.

import SwiftUI

struct UserProfileView: View {
    var body: some View {
        VStack(alignment: .leading, spacing: 16) {
            HStack {
                Image("profile_picture")
                    .resizable()
                    .frame(width: 100, height: 100)
                    .clipShape(Circle())
                VStack(alignment: .leading) {
                    Text("John Doe")
                        .font(.title)
                    Text("iOS Developer")
                        .font(.subheadline)
                        .foregroundColor(.gray)
                }
            }
            Text("About Me")
                .font(.headline)
            Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent commodo cursus magna, vel scelerisque nisl consectetur et.")
        }
        .padding()
    }
}

Step 1: Create a Profile Image Component

First, let’s extract the profile image into its own component. This component will be reusable anywhere you need to display a circular profile image.

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

Step 2: Create a User Info Component

Next, we’ll extract the user’s name and job title into a separate component. This makes it easier to manage and reuse the user information display.

struct UserInfoView: View {
    var name: String
    var jobTitle: String
    
    var body: some View {
        VStack(alignment: .leading) {
            Text(name)
                .font(.title)
            Text(jobTitle)
                .font(.subheadline)
                .foregroundColor(.gray)
        }
    }
}

Step 3: Assemble the Components

Now, let’s refactor the UserProfileView to use the new components we’ve created.

struct UserProfileView: View {
    var body: some View {
        VStack(alignment: .leading, spacing: 16) {
            HStack {
                ProfileImageView(imageName: "profile_picture")
                UserInfoView(name: "John Doe", jobTitle: "iOS Developer")
            }
            Text("About Me")
                .font(.headline)
            Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent commodo cursus magna, vel scelerisque nisl consectetur et.")
        }
        .padding()
    }
}

Final Touch: Adding Documentation

For better maintainability, it’s a good practice to document your components. Adding comments explaining the purpose and usage of each component can be very helpful, especially in larger teams.

/// A view that displays a circular profile image.
struct ProfileImageView: View {
    var imageName: String
    
    var body: some View {
        Image(imageName)
            .resizable()
            .frame(width: 100, height: 100)
            .clipShape(Circle())
    }
}

/// A view that displays the user's name and job title.
struct UserInfoView: View {
    var name: String
    var jobTitle: String
    
    var body: some View {
        VStack(alignment: .leading) {
            Text(name)
                .font(.title)
            Text(jobTitle)
                .font(.subheadline)
                .foregroundColor(.gray)
        }
    }
}

Conclusion

By splitting your SwiftUI views into smaller, reusable components, you can create more maintainable and scalable code. This approach not only enhances readability and reusability but also makes it easier to manage complex UIs. Start by identifying logical sections of your UI, extract them into separate components, and enjoy the benefits of a cleaner and more modular codebase. Happy coding!

Our mission

Effect UI for
your next project

We are a team of talented designers making iOS components to help developers build outstanding apps faster with less effort and best design.