Activity 1
Design a filter delegate
Create a filter chip view that reports the selected filter using a class-bound protocol and weak delegate.
Hint: The event should communicate the selected value, not which pixel was tapped.
UIKit Development
Connect user intent to application behavior with actions, delegates, gestures, and safe ownership boundaries.
Before you begin
Learning stage
Controls turn physical interaction into semantic events. You can connect them to selector-based target–action or attach UIAction closures. The handler should translate the event into an application intention—save, retry, select—not contain an entire workflow inside the visual component.
Delegation models an ongoing one-to-one collaboration. The delegating object defines a protocol, holds a weak delegate when the delegate owns or outlives it, and reports meaningful events. Data source protocols answer questions; delegate protocols commonly report choices or customize behavior.
Gesture recognizers are appropriate for spatial gestures on views, such as pinch or pan. Do not replace buttons with gestures simply for styling. Consider competition between gestures, touch cancellation, keyboard and pointer input, accessibility actions, and whether repeated configuration might register the same handler twice.
Learning stage
A reusable rating view reports a semantic choice without owning the feature workflow.
protocol RatingViewDelegate: AnyObject {
func ratingView(_ view: RatingView, didSelect rating: Int)
}
final class RatingView: UIStackView {
weak var delegate: RatingViewDelegate?
override init(frame: CGRect) {
super.init(frame: frame)
axis = .horizontal
spacing = 8
for rating in 1...5 {
var config = UIButton.Configuration.plain()
config.image = UIImage(systemName: "star")
let button = UIButton(configuration: config)
button.accessibilityLabel = "Rate (rating) out of 5"
button.addAction(UIAction { [weak self] _ in
guard let self else { return }
self.delegate?.ratingView(self, didSelect: rating)
}, for: .primaryActionTriggered)
addArrangedSubview(button)
}
}
required init(coder: NSCoder) { fatalError("Use init(frame:)") }
}Learning stage
Connect the UIKit concept to complete, maintainable application features.
Learning stage
Identify lifecycle, ownership, identity, layout, accessibility, and user-experience risks.
Learning stage
Build the behavior in a small Xcode project and inspect it across realistic states.
Activity 1
Create a filter chip view that reports the selected filter using a class-bound protocol and weak delegate.
Hint: The event should communicate the selected value, not which pixel was tapped.
Activity 2
For save, card selection, image zoom, text editing, and list data, choose control action, delegate, gesture, or data source and justify each.
Hint: Begin with semantic intent and accessibility.
Learning stage
Answer each question before revealing the explanation.
QUESTION 1
To avoid an ownership cycle when the delegate owns the delegating object
The relationship communicates events but usually should not extend the delegate's lifetime.
QUESTION 2
When interpreting a spatial gesture such as pan, pinch, rotation, or a tap on non-control content is central to the interaction.
A standard button remains better for a normal semantic action.
Learning stage
Explain the design in terms of lifecycle, identity, ownership, system behavior, and trade-offs.
Short answer: Use control actions for discrete UI events, a focused closure for local one-off callbacks, and delegation for a continuing structured relationship.
I consider semantics, lifetime, multiplicity, and ownership. UIAction is concise for control events. A closure works for one focused callback if capture behavior is clear. A class-bound weak delegate scales to multiple related events and customization points without coupling the component to a feature controller.
Possible follow-ups
Learning stage
Interaction APIs should translate input into semantic intent while preserving accessibility and clear object lifetimes.