Building iOS Apps with SwiftUI: A Complete Tutorial

Master SwiftUI fundamentals and create your first iOS app with this step-by-step guide covering views, state management, and animation.

What You'll Learn

SwiftUI represents Apple's modern approach to building user interfaces across all Apple platforms. Unlike traditional imperative UI frameworks where you describe how to make changes step by step, SwiftUI lets you declare what your interface should look like, and the framework handles the underlying mechanics of rendering and updating.

This comprehensive tutorial walks you through building a fully functional iOS app called "WhyNotTry" that suggests random activities to users. Along the way, you'll master:

  • Views and Modifiers: The building blocks of SwiftUI interfaces
  • Layout with Stacks: VStack, HStack, and ZStack for organizing views
  • State Management: @State and reactive data flow
  • User Interaction: Buttons, actions, and event handling
  • Animation: Smooth transitions and polished UX

SwiftUI has been available since iOS 13 and is Apple's recommended framework for new iOS development. The declarative paradigm shift makes your code more predictable, easier to read, and significantly faster to develop.

If you're exploring cross-platform options, compare SwiftUI with frameworks like Flutter or React Native to find the right approach for your project.

Getting Started: Xcode Setup and Your First Project

Before writing a single line of SwiftUI code, you need the right development environment. Xcode is Apple's integrated development environment (IDE) and the only tool you need to build iOS apps. It comes bundled with Swift, the SwiftUI framework, simulators for testing, and all the necessary tooling for development, testing, and distribution.

Installing Xcode

Xcode is available free from the Mac App Store. Simply search for "Xcode" and download the latest version. The installation process typically takes several minutes as it includes not only the IDE but also SDKs for all Apple platforms, simulators, documentation, and additional components.

Once installed, launch Xcode and select "Create a new Xcode Project" from the welcome screen. You'll see several project templates organized by platform and application type. For this tutorial, select the iOS tab at the top, then choose the "App" template and click Next.

Configuring Your Project

Xcode will prompt you for several pieces of configuration information:

SettingDescriptionExample
Product NameHuman-readable app nameWhyNotTry
Organization IdentifierUnique identifier (reverse-domain)com.example
InterfaceUI framework selectionSwiftUI
LanguageProgramming languageSwift

You can uncheck Core Data and Include Tests for this tutorial since we won't be using either feature.

Understanding the Project Structure

After clicking Next and choosing where to save your project, Xcode creates a complete directory structure. The most important file for our purposes is ContentView.swift, which contains the default SwiftUI view code.

The preview canvas on the right side of Xcode is one of SwiftUI's most powerful features. As you modify your code, the preview updates immediately--often within milliseconds. This tight feedback loop makes experimentation rapid and encourages iterative design.

Following the official Swift.org tutorial is an excellent way to get started with building your first iOS app using SwiftUI.

For teams building both web and mobile applications, consider how your iOS development integrates with your /services/web-development/ workflow for a cohesive digital presence.

ContentView.swift - Your First SwiftUI View
1import SwiftUI2 3struct ContentView: View {4 var body: some View {5 Text("Hello, SwiftUI!")6 }7}8 9#Preview {10 ContentView()11}

Understanding Views and Modifiers

At the heart of SwiftUI lies the concept of a view. A view represents a piece of user interface--anything from a single character of text to a complex interactive control. Everything you see in a SwiftUI app is built from views composed together.

The View Protocol

The View protocol is remarkably simple but powerful. Any type that conforms to View must provide a single computed property called body that returns some View. SwiftUI's view system is compositional: simple views combine to create complex interfaces.

View Modifiers

While basic views like Text are useful, real applications require customization. SwiftUI provides modifiers to change how a view looks or behaves:

Text("Hello, SwiftUI!")
 .font(.largeTitle)
 .fontWeight(.bold)
 .foregroundColor(.blue)

Each modifier wraps the previous view in a new view with its specific change applied. The order of modifiers matters because each one creates a new view wrapper.

Color and SF Symbols

iOS includes an extensive color palette that works seamlessly with light and dark mode:

Circle()
 .fill(.blue)

SF Symbols is Apple's icon library containing thousands of symbols designed to match Apple's design language:

Image(systemName: "figure.archery")
 .font(.system(size: 144))
 .foregroundColor(.white)

You can download the SF Symbols app from Apple's developer website to browse all available symbols and their various weights and configurations.

Layout with Stacks

SwiftUI provides three stack types for arranging views

VStack

Arranges views from top to bottom. Perfect for vertical layouts with titles, content, and buttons stacked sequentially.

HStack

Arranges views from left to right. Ideal for creating rows with icons, labels, and actions displayed horizontally.

ZStack

Layers views on top of each other. Essential for overlays, backgrounds with content, and complex compositions.

Building a Static User Interface

Now that you understand views and modifiers, let's build the visual foundation of our "WhyNotTry" app. We'll create a static interface first, then add interactivity and state management.

Drawing Shapes

SwiftUI includes several basic shape views:

Circle()

Shapes in SwiftUI are designed to fill all available space by default. Combine with fill() and padding():

Circle()
 .fill(.blue)
 .padding()

Overlay and Composition

The overlay() modifier places one view on top of another:

Circle()
 .fill(.blue)
 .padding()
 .overlay(
 Image(systemName: "figure.archery")
 .font(.system(size: 144))
 .foregroundColor(.white)
 )

Nested Stacks

Stacks can be nested arbitrarily to create sophisticated layouts:

VStack {
 Text("Why not try...")
 .font(.largeTitle.bold())

 VStack {
 Circle()
 .fill(.blue)
 .padding()
 .overlay(
 Image(systemName: "figure.archery")
 .font(.system(size: 144))
 .foregroundColor(.white)
 )

 Text("Archery!")
 .font(.title)
 }
}

This nested structure gives you precise control over the arrangement of your content.

Bringing Your App to Life: State and Interactivity

Real apps respond to user input and change over time. SwiftUI's state management system makes this surprisingly elegant.

The @State Property Wrapper

For properties that belong to a single view and can change, use the @State property wrapper:

@State private var selected = "Archery"

The @State wrapper marks the property as mutable and tells SwiftUI to monitor changes. When the value changes, any views that depend on it update automatically.

Properties marked with @State should typically be marked private to enforce good encapsulation.

Managing Collections of Data

For activity suggestions, we need a collection of possible activities:

var activities = ["Archery", "Baseball", "Basketball", "Bowling",
 "Boxing", "Cricket", "Curling", "Fencing",
 "Golf", "Hiking", "Lacrosse", "Rugby", "Squash"]

Swift arrays provide randomElement() to pick a random item:

selected = activities.randomElement() ?? "Archery"

The ?? operator provides a fallback value in case the array is empty.

Interactive Buttons

Buttons in SwiftUI combine a label with an action:

Button("Try again") {
 selected = activities.randomElement() ?? "Archery"
}
.buttonStyle(.borderedProminent)

The .borderedProminent style gives the button a prominent appearance with blue background and white text. Following the Swift.org SwiftUI tutorial provides additional examples of interactive UI components.

If you're coming from other mobile frameworks, understanding how SwiftUI handles state with property wrappers like @State is a key difference from patterns you may have used before. Compare this to managing state in Flutter to see the different approaches mobile frameworks take.

Complete Interactive ContentView
1struct ContentView: View {2 var activities = ["Archery", "Baseball", "Basketball", "Bowling",3 "Boxing", "Cricket", "Curling", "Fencing",4 "Golf", "Hiking", "Lacrosse", "Rugby", "Squash"]5 6 @State private var selected = "Archery"7 8 var body: some View {9 VStack {10 Text("Why not try...")11 .font(.largeTitle.bold())12 13 VStack {14 Circle()15 .fill(.blue)16 .padding()17 .overlay(18 Image(systemName: "figure.\(selected.lowercased())")19 .font(.system(size: 144))20 .foregroundColor(.white)21 )22 23 Text("\(selected)!")24 .font(.title)25 }26 27 Button("Try again") {28 selected = activities.randomElement() ?? "Archery"29 }30 .buttonStyle(.borderedProminent)31 }32 }33}

Adding Polish: Color, Spacing, and Animation

A great app feels refined and responsive. Let's enhance our app with random colors, proper spacing, and smooth animations.

Random Colors

Add a collection of colors and update the circle's fill:

var colors: [Color] = [.blue, .cyan, .gray, .green, .indigo,
 .mint, .orange, .pink, .purple, .red]

Circle()
 .fill(colors.randomElement() ?? .blue)

Spacing with Spacer

The Spacer view expands to fill available space, pushing other views away:

VStack {
 // Content at top
}
Spacer()
// Button at bottom

Animated Transitions

SwiftUI makes animation elegant with withAnimation():

Button("Try again") {
 withAnimation {
 selected = activities.randomElement() ?? "Archery"
 }
}
.buttonStyle(.borderedProminent)

Customize the animation:

withAnimation(.easeInOut(duration: 1)) {
 selected = activities.randomElement() ?? "Archery"
}

Smooth View Transitions

Treat an entire view as a single unit that gets replaced:

@State private var id = 1

VStack {
 // activity display
}
.transition(.slide)
.id(id)

When id changes, SwiftUI applies the transition. Combined with withAnimation(), this creates smooth entry and exit animations.

Best Practices for SwiftUI Development

As you develop more complex SwiftUI applications, these practices will help you write maintainable, performant code.

Access Control

Mark view-local state as private to prevent accidental access from outside the view:

@State private var selected = "Archery"

Organized Code Structure

Keep related functionality together. If a view needs data, define that data as properties on the view. If multiple views need the same data, consider extracting it into a separate model.

View Modularity

Break complex views into smaller, reusable components. If you find yourself copying the same view configuration multiple times, consider creating a custom view that encapsulates that configuration.

Performance Considerations

SwiftUI is designed to be efficient, but be mindful of expensive operations in your views. Avoid doing heavy computation in the body property--use @State and computed properties strategically.

Where to Go from Here

This tutorial covered the fundamental concepts of SwiftUI development, but there's much more to explore:

TopicDescription
Drawing and GraphicsCustom shapes, paths, and Canvas views
NavigationStack-based and tab-based app navigation
Lists and CollectionsEfficient display of large data sets
GesturesCustom touch interactions
Data PersistenceSaving and loading app state
NetworkingCommunicating with web services

Learning Resources

  • Apple's Official Documentation: Extensive coverage of all SwiftUI features
  • Hacking with Swift: Hundreds of SwiftUI examples for all skill levels
  • Apple Sample Code: Real-world patterns for production applications

Continue Your Mobile Development Journey

Once you've mastered SwiftUI basics, expand your skills with these related resources:

Our mobile development services team specializes in building iOS applications with SwiftUI. Whether you're starting a new project or looking to modernize an existing app, we can help bring your vision to life.

Frequently Asked Questions

Do I need a Mac to build iOS apps with SwiftUI?

Yes, Xcode is required to build iOS apps and is only available on macOS. You'll need a Mac running a recent version of macOS to follow this tutorial.

Is SwiftUI production-ready for enterprise apps?

Absolutely. SwiftUI has been available since iOS 13 and is Apple's recommended framework for new iOS development. Major apps across the App Store use SwiftUI.

Can I mix SwiftUI with UIKit?

Yes, SwiftUI and UIKit can coexist in the same project. You can use UIKit views in SwiftUI and vice versa using the provided integration APIs.

What's the difference between @State and @StateObject?

@State is for simple, view-local data. @StateObject is for reference types (classes) that need to be shared across views and maintain their state across view updates.

Does SwiftUI work on older iOS versions?

SwiftUI requires iOS 13 or later. For apps supporting older iOS versions, you'll need to use UIKit or provide fallback experiences.

Ready to Build Your Next iOS App?

Our team specializes in SwiftUI development and cross-platform mobile solutions. Let's discuss your project.

Sources

  1. Swift.org: Build an iOS app with SwiftUI - Official step-by-step tutorial with complete code examples
  2. Apple Developer: Introducing SwiftUI - Official framework documentation
  3. Apple Developer: App Development Training - Comprehensive learning curriculum