How to Create a Button in SwiftUI

What you’ll build or solve

Create a button in SwiftUI by using the Button view with a label and an action. You’ll define a button using either the simple text initializer or the custom label initializer.

When this approach works best

Creating a button in SwiftUI works best when:

  • You need to trigger an action, such as saving data or navigating.
  • You want a reusable control inside a custom view.
  • You need either a simple text button or a button with custom layout.

This is a bad idea if you need advanced gestures like drag or long press with complex state handling. In that case, use gesture modifiers instead.

Prerequisites

  • Xcode with a SwiftUI project
  • Basic understanding of SwiftUI views

Step-by-step instructions

Step 1: Create a button with a text label

Use the Button initializer that takes a string and an action closure.

importSwiftUI

structContentView:View {
varbody:someView {
Button("Tap Me") {
print("Button tapped")
        }
        .padding()
    }
}

#Preview {
ContentView()
}

The first parameter is the button’s label. The closure runs when the button is tapped.

Step 2: Create a button with a custom label

Use the Button(action:label:) initializer to build a custom label view.

importSwiftUI

structContentView:View {
varbody:someView {
Button(action: {
print("Custom button tapped")
        }) {
HStack {
Image(systemName:"star.fill")
Text("Favorite")
            }
        }
        .padding()
    }
}

This form allows you to combine text, images, and layout inside the label.

What to look for

  • The action closure is required.
  • The custom label can contain any SwiftUI view.
  • You can later connect the action to @State, @Binding, or a model.
  • You can apply styling using modifiers like .buttonStyle() or .padding().

Examples you can copy

Example 1: Simple print action

importSwiftUI

structSimpleButtonView:View {
varbody:someView {
Button("Log Message") {
print("Log button tapped")
        }
    }
}

Example 2: Button with icon and text

importSwiftUI

structIconTextButtonView:View {
varbody:someView {
Button(action: {
print("Share tapped")
        }) {
HStack {
Image(systemName:"square.and.arrow.up")
Text("Share")
            }
        }
    }
}

Example 3: Custom layout inside label

importSwiftUI

structComplexLabelButtonView:View {
varbody:someView {
Button(action: {
print("Profile tapped")
        }) {
VStack {
Image(systemName:"person.circle")
                    .font(.largeTitle)
Text("Profile")
            }
        }
    }
}

The label can use stacks, images, text, or any other SwiftUI view.

Common mistakes and how to fix them

Mistake 1: Forgetting the action closure

What you might do:

Button("Tap Me")

Why it breaks: Button requires an action closure, so this will not compile.

Correct approach:

Button("Tap Me") {
print("Tapped")
}

Mistake 2: Mixing up initializer syntax

What you might do:

Button("Tap Me",action: {
print("Tapped")
}) {
Text("Label")
}

Why it breaks: You are combining both initializer forms in one declaration.

Correct approach: Use one form only.

Text-only form:

Button("Tap Me") {
print("Tapped")
}

Custom label form:

Button(action: {
print("Tapped")
}) {
Text("Tap Me")
}

Troubleshooting

  • If you see a compiler error about missing parameters, confirm you provided an action closure.
  • If the label does not appear, check that your custom label returns a valid SwiftUI view.
  • If the button does not respond, confirm your action closure contains executable code.
  • If previews fail, verify the view compiles independently before embedding it elsewhere.

Quick recap

  • Use Button("Title") { action } for a simple text button.
  • Use Button(action:) { label } for custom layouts.
  • Provide an action closure every time.
  • Keep initializer forms separate, do not mix them.
  • Build labels with any SwiftUI view.