Bird
Raised Fist0
iOS Swiftmobile~15 mins

Button and action handling in iOS Swift - Deep Dive

Choose your learning style10 modes available
Overview - Button and action handling
What is it?
Button and action handling is about creating buttons in an app and making them do something when tapped. A button is a simple way for users to interact with the app. When a user taps a button, the app runs some code called an action. This lets the app respond to user choices.
Why it matters
Without buttons and actions, apps would be static and users could not control what happens. Buttons let users tell the app what they want, like submitting a form or moving to another screen. This interaction is the core of making apps useful and fun.
Where it fits
Before learning this, you should know basic Swift syntax and how to create a simple app. After this, you can learn about more complex user interactions, like gestures or animations, and how to manage app navigation.
Mental Model
Core Idea
A button is a visible control that triggers a specific piece of code when tapped by the user.
Think of it like...
A button in an app is like a light switch on a wall: when you press it, it turns the light on or off. The button sends a signal to do something.
┌─────────────┐
│   Button    │
└─────┬───────┘
      │ Tap
      ▼
┌─────────────┐
│   Action    │
│ (code runs) │
└─────────────┘
Build-Up - 7 Steps
1
FoundationCreating a basic UIButton
🤔
Concept: Learn how to add a button to the screen using Swift and UIKit.
In your ViewController, create a UIButton instance. Set its title and position it on the screen using frame or Auto Layout. Add it as a subview to the main view. Example: let button = UIButton(type: .system) button.setTitle("Tap me", for: .normal) button.frame = CGRect(x: 100, y: 100, width: 100, height: 50) view.addSubview(button)
Result
A button labeled 'Tap me' appears on the screen at the specified position.
Understanding how to create and display a button is the first step to making interactive apps.
2
FoundationConnecting button to action method
🤔
Concept: Learn how to make the button respond when tapped by linking it to a function.
Use the addTarget method on the button to connect it to an action method. The method runs when the button is tapped. Example: button.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside) @objc func buttonTapped() { print("Button was tapped") }
Result
When the user taps the button, the console prints 'Button was tapped'.
Linking a button to an action method lets the app respond to user input.
3
IntermediateUsing Interface Builder for buttons
🤔Before reading on: do you think you can connect a button to code without writing code to create it? Commit to yes or no.
Concept: Learn how to create buttons visually in Storyboard and connect them to code using IBAction.
In Xcode's Interface Builder, drag a UIButton onto your view. Then Control-drag from the button to your ViewController code to create an IBAction method. This method runs when the button is tapped. Example: @IBAction func buttonPressed(_ sender: UIButton) { print("Button pressed via IBAction") }
Result
Tapping the button triggers the IBAction method and prints the message.
Using Interface Builder speeds up UI creation and connects UI elements to code cleanly.
4
IntermediateHandling multiple buttons with one action
🤔Before reading on: can one action method handle taps from multiple buttons? Commit to yes or no.
Concept: Learn how to use one action method to respond differently depending on which button was tapped.
Connect multiple buttons to the same IBAction. Use the sender parameter to identify which button was tapped. Example: @IBAction func buttonTapped(_ sender: UIButton) { if sender == button1 { print("Button 1 tapped") } else if sender == button2 { print("Button 2 tapped") } }
Result
The app prints different messages depending on which button the user taps.
One action method can handle many buttons, making code cleaner and easier to maintain.
5
IntermediateChanging button appearance on tap
🤔Before reading on: do you think the button changes appearance automatically when tapped? Commit to yes or no.
Concept: Learn how to change button colors or images when the user taps or holds the button.
UIButton supports different states like normal, highlighted, and disabled. Set different titles or colors for these states. Example: button.setTitleColor(.blue, for: .normal) button.setTitleColor(.red, for: .highlighted)
Result
The button text color changes from blue to red when the user taps and holds it.
Using button states improves user feedback and app polish.
6
AdvancedDebouncing button taps to avoid multiple triggers
🤔Before reading on: do you think tapping a button rapidly triggers the action multiple times? Commit to yes or no.
Concept: Learn how to prevent multiple rapid taps from triggering the action repeatedly, which can cause bugs.
Disable the button immediately when tapped and re-enable it after the action finishes. Example: @IBAction func buttonTapped(_ sender: UIButton) { sender.isEnabled = false // perform action DispatchQueue.main.asyncAfter(deadline: .now() + 1) { sender.isEnabled = true } }
Result
Rapid taps only trigger the action once per second, preventing accidental multiple actions.
Controlling tap frequency avoids crashes or duplicate operations in real apps.
7
ExpertCustom button subclasses for reusable actions
🤔Before reading on: do you think subclassing UIButton can help reuse complex tap behavior? Commit to yes or no.
Concept: Learn how to create a custom button class that handles its own tap actions and appearance for reuse across the app.
Subclass UIButton and override touch events or add target-action inside the class. This encapsulates behavior. Example: class CustomButton: UIButton { override init(frame: CGRect) { super.init(frame: frame) addTarget(self, action: #selector(tapped), for: .touchUpInside) } required init?(coder: NSCoder) { super.init(coder: coder) } @objc func tapped() { print("Custom button tapped") } }
Result
Any CustomButton instance automatically handles taps with the custom code.
Encapsulating button behavior in subclasses improves code reuse and consistency.
Under the Hood
When a user taps a button, the iOS system detects the touch event and sends it to the app's event loop. UIKit matches the event to the button's target-action pair and calls the linked method on the target object. The method runs on the main thread, allowing UI updates or logic to execute immediately.
Why designed this way?
The target-action pattern was designed to separate UI controls from the code that handles their events. This decoupling allows flexible connections between buttons and actions, supports multiple controls sharing actions, and fits well with the event-driven nature of iOS apps.
User Tap
   │
   ▼
┌───────────────┐
│ UIKit detects  │
│ touch event   │
└──────┬────────┘
       │
       ▼
┌───────────────┐
│ Button control│
│ sends action  │
└──────┬────────┘
       │
       ▼
┌───────────────┐
│ Target object │
│ runs method   │
└───────────────┘
Myth Busters - 4 Common Misconceptions
Quick: does tapping a button always immediately run the linked code? Commit to yes or no.
Common Belief:Tapping a button instantly runs the action code without delay.
Tap to reveal reality
Reality:The action runs on the main thread after the touch event is processed, which may be delayed if the main thread is busy.
Why it matters:Assuming instant execution can lead to UI freezes or missed taps if the main thread is blocked.
Quick: can one button have multiple actions for the same event? Commit to yes or no.
Common Belief:A button can only have one action method for a given event like touchUpInside.
Tap to reveal reality
Reality:A button can have multiple target-action pairs for the same event, all of which run in order.
Why it matters:Knowing this helps avoid bugs where multiple handlers unexpectedly run or are forgotten.
Quick: does disabling a button prevent its action from running? Commit to yes or no.
Common Belief:Disabling a button stops it from receiving taps and running actions.
Tap to reveal reality
Reality:A disabled button ignores touch events and does not run actions until re-enabled.
Why it matters:Disabling buttons is a simple way to prevent unwanted repeated actions or invalid input.
Quick: does changing a button's title color affect its tap behavior? Commit to yes or no.
Common Belief:Changing appearance like title color changes how the button responds to taps.
Tap to reveal reality
Reality:Appearance changes do not affect tap detection or action execution.
Why it matters:Separating visual styling from behavior prevents confusion when debugging tap issues.
Expert Zone
1
UIButton's target-action mechanism uses a weak reference to the target to avoid retain cycles, so forgetting to keep a strong reference can cause actions not to fire.
2
The touchUpInside event only triggers when the finger lifts inside the button bounds, so dragging finger outside cancels the tap, which is important for user experience.
3
Custom buttons can override beginTracking and endTracking methods to customize touch handling beyond target-action.
When NOT to use
For complex gestures or multi-touch interactions, use UIGestureRecognizer instead of buttons. Also, for non-UI logic triggered by events, consider other patterns like Combine or delegation.
Production Patterns
In production apps, buttons are often connected via Interface Builder for speed, but programmatic creation is used for dynamic interfaces. Debouncing taps and disabling buttons during network calls are common to prevent duplicate actions.
Connections
Event-driven programming
Button action handling is a specific example of event-driven programming where user input triggers code execution.
Understanding event-driven programming helps grasp how buttons fit into the app's reactive flow.
Human-computer interaction (HCI)
Buttons are fundamental UI elements studied in HCI to optimize user experience and accessibility.
Knowing HCI principles guides better button design and action feedback for users.
Electrical switches
Buttons in software mimic physical switches that open or close circuits to control devices.
Recognizing this hardware-software parallel clarifies why buttons have states and trigger actions.
Common Pitfalls
#1Button action method not marked with @objc
Wrong approach:button.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside) func buttonTapped() { print("Tapped") }
Correct approach:button.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside) @objc func buttonTapped() { print("Tapped") }
Root cause:Swift methods used as selectors must be exposed to Objective-C runtime with @objc.
#2Forgetting to add button as subview
Wrong approach:let button = UIButton(type: .system) button.setTitle("Tap", for: .normal) // missing view.addSubview(button)
Correct approach:let button = UIButton(type: .system) button.setTitle("Tap", for: .normal) view.addSubview(button)
Root cause:Creating a button alone does not display it; it must be added to the view hierarchy.
#3Using frame without considering device size
Wrong approach:button.frame = CGRect(x: 100, y: 100, width: 100, height: 50)
Correct approach:Use Auto Layout constraints or safe area guides to position buttons responsively.
Root cause:Hardcoded frames do not adapt to different screen sizes or orientations.
Key Takeaways
Buttons are the main way users interact with apps by triggering actions when tapped.
Connecting buttons to action methods uses the target-action pattern, which decouples UI from code.
Buttons can be created programmatically or via Interface Builder, each with its own benefits.
Handling multiple buttons with one action and managing button states improves code clarity and user experience.
Advanced techniques like debouncing taps and custom button subclasses help build robust, reusable UI components.

Practice

(1/5)
1. What is the main purpose of a UIButton in an iOS app?
easy
A. To let users tap and trigger actions
B. To display static text only
C. To store data persistently
D. To manage app navigation automatically

Solution

  1. Step 1: Understand UIButton role

    A UIButton is a UI element that users can tap to perform an action.
  2. Step 2: Compare options with UIButton purpose

    Only To let users tap and trigger actions describes this interaction purpose correctly.
  3. Final Answer:

    To let users tap and trigger actions -> Option A
  4. Quick Check:

    UIButton = user tap action [OK]
Hint: Buttons are for user taps triggering actions [OK]
Common Mistakes:
  • Confusing buttons with labels
  • Thinking buttons store data
  • Assuming buttons handle navigation automatically
2. Which of the following is the correct way to add an action to a UIButton in Swift?
easy
A. button.onTap = buttonTapped()
B. button.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
C. button.addAction(#selector(buttonTapped))
D. button.action = #selector(buttonTapped)

Solution

  1. Step 1: Recall UIButton action syntax

    The correct method is addTarget(_:action:for:) with #selector for the method.
  2. Step 2: Match syntax with options

    Only button.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside) uses the correct method and parameters.
  3. Final Answer:

    button.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside) -> Option B
  4. Quick Check:

    addTarget + #selector + .touchUpInside = correct [OK]
Hint: Use addTarget with #selector and .touchUpInside [OK]
Common Mistakes:
  • Using nonexistent addAction method
  • Assigning action directly without addTarget
  • Calling the selector method instead of referencing it
3. Given the code below, what happens when the button is tapped?
let button = UIButton()
button.addTarget(self, action: #selector(showMessage), for: .touchUpInside)

@objc func showMessage() {
    print("Button was tapped")
}
medium
A. The app crashes due to missing button title
B. Nothing happens because the method is missing @objc
C. The message "Button was tapped" is printed to the console
D. The button changes color automatically

Solution

  1. Step 1: Check action method annotation

    The method showMessage is marked with @objc, so it can be called by the button.
  2. Step 2: Understand button tap behavior

    When tapped, the button triggers showMessage, which prints the message.
  3. Final Answer:

    The message "Button was tapped" is printed to the console -> Option C
  4. Quick Check:

    @objc method called on tap = print message [OK]
Hint: @objc method runs on button tap printing message [OK]
Common Mistakes:
  • Forgetting @objc on action method
  • Expecting UI changes without code
  • Confusing button title with action effect
4. Identify the error in this code snippet that prevents the button action from working:
let button = UIButton()
button.addTarget(self, action: #selector(buttonPressed), for: .touchUpInside)

func buttonPressed() {
    print("Pressed")
}
medium
A. The button title is not set
B. The button is not added to the view
C. The selector syntax is incorrect
D. The action method is missing the @objc attribute

Solution

  1. Step 1: Check method declaration for selector

    Methods used with #selector must be marked @objc to be visible to Objective-C runtime.
  2. Step 2: Verify other code parts

    While adding button to view and title are important, they don't prevent action from being called.
  3. Final Answer:

    The action method is missing the @objc attribute -> Option D
  4. Quick Check:

    @objc missing on action method = no call [OK]
Hint: Action methods need @objc to be called by button [OK]
Common Mistakes:
  • Ignoring @objc requirement
  • Thinking button must have title for action
  • Assuming selector syntax is wrong when it's correct
5. You want to create a button that changes its title to "Clicked" when tapped. Which code snippet correctly implements this behavior?
let button = UIButton()
button.setTitle("Tap me", for: .normal)
button.addTarget(self, action: #selector(changeTitle), for: .touchUpInside)

@objc func changeTitle() {
    // What goes here?
}
hard
A. self.button.setTitle("Clicked", for: .normal)
B. button.setTitle("Clicked", for: .normal)
C. button.title = "Clicked"
D. changeTitle.title = "Clicked"

Solution

  1. Step 1: Understand scope of button variable

    The button variable is declared outside the method, so inside changeTitle() you must reference it properly, usually as self.button.
  2. Step 2: Use correct method to change title

    UIButton's title is changed using setTitle(_:for:) method, not by assigning to a property.
  3. Final Answer:

    self.button.setTitle("Clicked", for: .normal) -> Option A
  4. Quick Check:

    Use self.button.setTitle to update title [OK]
Hint: Use self.button.setTitle("Clicked", for: .normal) inside action [OK]
Common Mistakes:
  • Trying to assign title directly
  • Using button without self when needed
  • Calling setTitle on wrong object
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard