← Back to list

Understanding SwiftUI View & Modifiers

SwiftUI provides the views in the same way as UIKit to present our content on the screen. SwiftUI lets us ignore Interface builder and…

Raghavkakria · 2025-01-24 10:25 · 0 claps · 5.5 min read
#swiftui-views #swiftui-viewmodifier
Open on Medium ↗
Wiki topics: 📱 · Mobile Development

Understanding SwiftUI View & Modifiers

SwiftUI provides the views in the same way as UIKit to present our content on the screen. SwiftUI lets us ignore Interface builder and Storyboards for laying out the user interface. SwiftUI gives the way to preview the UI as you write the code and as well generates the code as you drag and drop the views on to the canvas. In the editor, we can see the code and preview side by side and change to one side will update the other. So, in SwiftUI code and preview are always in sync.

Views

In SwiftUI, every element is a view. A view represents a user interface component, such as a button, label, or an entire screen. Views can be composed of other views, allowing you to build intricate interfaces from basic elements.

Every view in SwiftUI conforms to the View Protocol.

Here’s a fundamental SwiftUI view example:

import SwiftUI

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

In this example, the body property returns some View, indicating that it returns a type that conforms to the View protocol, but the specific type is not exposed. This concept is known as an opaque return type.

Why is View a struct and not a class anymore?

One of the fundamental principles of SwiftUI is to have a single source of truth in your code. A traditional UIKit approach of having a base UIView class and all other views inherit from it has a demerit wherein we have multiple stored properties in our view inherited from parent UIView. You only define properties that you want to use unlike in UIKit where you inherit a number of properties from your parent view.

SwiftUI tends to make views pretty lightweight and what better option than a value type with no headache of reference counting and retain cycles. Reference types are messier to maintain. You can alter your properties from anywhere in your code. Swift UI also makes you be responsible for any views and their own state. Views are independent and isolated from one another. Any changes to a particular view will not affect any other unless they are bind by some common source of truth. It’s allocated on the stack, and it’s passed by value.

Body of a SwiftUI View

Let us open up the View protocol

public protocol View {
  associatedtype Body : View
  var body: Self.Body { get }
}

The View protocol has an associated type Body which is constrained to be any type conforming View protocol. The body is your actual content that will be rendered on screen. SwiftUI will infer the associated type by the implementation of the body computed property. Let us look at the implementation.

Reasons for Using some view

1. Type Inference and Simplicity

The use of some View allows Swift to infer the return type of a view without requiring the developer to specify it explicitly. This simplifies the code and makes it more readable. For instance, consider the complexity if you had to specify the exact return type of every view:

var body: TupleView<(Text, Padding)> {
    return Text("Hello, world!").padding()
}

By using some View, SwiftUI reduces boilerplate code and keeps the focus on what the view does rather than its exact type.

2. View Composition

Views in SwiftUI are composed declaratively. We can combine simple views to create more complex interfaces

var body: some View {
    VStack {
        Text("Welcome")
        Image(systemName: "star")
        Button(action: {
            print("Button tapped")
        }){
            Text("Tap me")
        }
    }
}

3. Flexibility in View Composition

SwiftUI’s view hierarchy is highly compositional. Views are often composed of other views, and the specific composition can change based on various conditions. Using some View allows for this flexibility without requiring the return type to change. For example:

var body: some View {
    if isActive {
        return Text("Active")
    } else {
        return Text("Inactive")
    }
}

With some View, you can return different views based on logic without changing the return type, as long as all returned types conform to the View protocol.

4. Improved Compilation Performance

Opaque return types like some View can lead to better compilation performance. By not exposing the exact type, the Swift compiler can optimize more effectively. This is particularly important in SwiftUI, where view hierarchies can become complex, and compile times can significantly impact development speed.

5. Encapsulation and Abstraction

Using some View promotes encapsulation by hiding the implementation details of the view. This abstraction allows developers to change the internal structure of a view without affecting the code that uses it. For instance, you can refactor a view to use different internal components without changing its interface:

var body: some View {
    VStack {
        Text("Hello")
        Text("World")
    }
}

Later, you can change it to:

var body: some View {
    HStack {
        Text("Hello")
        Text("World")
    }
}

The interface remains the same, while the internal implementation can vary.

Modifiers

Modifiers enable you to alter the appearance, behavior, position and interactions of the controls or views. For example font, opacity, padding, respond to taps, gestures, animations, transitions etc.

SwiftUI views are modified using a fluent syntax with modifiers that return new view instances. This allows for chaining modifications to configure the view’s appearance and behavior.

For instance, to change the text font and color of a label:

Text("Hello, SwiftUI!")
    .foregroundStyle(.blue) // change color of text to blue
    .font(.system(size: 24)) // sets the display as system font of size 24
  • Text("Hello, SwiftUI!"): Creates a text view with the specified string.
  • .foregroundStyle(.blue): Sets the text color to blue.
  • .font(.system(size: 24)): Sets the font size to 24.

Create a custom view modifier

Apart from built-in modifiers, we can create custom view modifiers.

Let’s say we have a set of styles that are used in many places in our app. For example, we could use a blue background with a subtle gradient that has rounded corners and a white foreground color. We can make this set of modifiers into a custom style that is used anywhere in our app.

Note that our CustomStyle inherits from ViewModifier, this allows us to make a modifier of our own. Inside our custom style, we are passing “content” into the body of our view, and that body returns the “some View” type.

In this tutorial, I’ll show you step by step how to create different custom view modifier for Text in SwiftUI:

We will create a struct named LargeBlueTitle in our example, we need to make our swiftUI Text as blue color with large title.

struct LargeBlueTitle {

}

conforms to the ViewModifier protocol

struct LargeBlueTitle: ViewModifier {

}

After conforms you will probably get an error Type ‘LargeBlueTitle’ does not conform to protocol ‘ViewModifier’ to solve this issue you need to implement the required body(content:) method. This method describes how to modify the view that is passed to it.

struct LargeBlueTitle: ViewModifier {
    func body(content: Content) -> some View {
        content
            .font(.largeTitle)
            .foregroundStyle(.blue)
            .padding(10)
    }
}

Here, you will add different modifiers to content in order to make it work.

you can pass parameters to a view modifier to make it more flexible. To get the padding values from the parent view, you can modify the LargeBlueTitle structure to accept parameters for the padding properties.

Here’s how you can modify your code to allow customizable padding properties:

struct LargeBlueTitle: ViewModifier {
    var padding: CGFloat

    func body(content: Content) -> some View {
        content
            .font(.largeTitle)
            .foregroundStyle(.blue)
            .padding(padding)
    }
}

At this point, we may apply it on Text using modifier(),

Text("Welcome")
    .modifier(LargeBlueTitle(padding: 10))

ViewModifiers can also be composed together to create more complex behaviors. For example, I could create a new CustomButton modifier that combines the LargeBlueTitle modifier with a background color:

struct CustomButton: ViewModifier {
    func body(content: Content) -> some View {
        content
            .modifier(LargeBlueTitle(padding: 10))
            .background(.red)
    }
}

Now, we have a reusable modifier that creates a button-like appearance for any SwiftUI view.

Button(action: {
        print("Button tapped")
    }){
        Text("Tap me")
    }
    .modifier(CustomButton())

Conclusion

The use of some View in SwiftUI is a powerful feature that simplifies UI development, enhances flexibility, improves compilation performance, and promotes encapsulation. By understanding and leveraging some View, developers can create more maintainable, performant, and readable SwiftUI applications. Embrace this feature to unlock the full potential of SwiftUI in your iOS development projects.

ViewModifier in SwiftUI is an essential tool for encapsulating view customization. It allows you to create reusable and consistent styling or behavior that can be applied across multiple views in a clean and modular way.


메타데이터
post_id
f40864d3cd6d
slug
understanding-swiftui-view-modifiers-f40864d3cd6d
url
https://medium.com/@raghavkakria1/understanding-swiftui-view-modifiers-f40864d3cd6d
canonical_url
https://medium.com/@raghavkakria1/understanding-swiftui-view-modifiers-f40864d3cd6d
author_url
https://medium.com/@raghavkakria1
status
ok
fetched_at
2026-08-08 00:02:55