Core Concepts
IBOutlets connect code to UI elements; IBActions respond to UI events:
class DetailViewController: UIViewController {
@IBOutlet weak var nameLabel: UILabel!
@IBOutlet weak var saveButton: UIButton!
@IBAction func saveTapped(_ sender: UIButton) {
nameLabel.text = "Saved!"
saveButton.isEnabled = false
}
}
The target-action mechanism connects UI control events to methods:
let slider = UISlider()
slider.addTarget(self, action: #selector(sliderChanged(_:)),
for: .valueChanged)
@objc func sliderChanged(_ sender: UISlider) {
print("Slider value: \(sender.value)")
}
Delegation allows one object to communicate back to another:
protocol OrderDelegate: AnyObject {
func orderDidComplete(orderId: String)
}
class OrderManager {
weak var delegate: OrderDelegate?
func processOrder() {
// Process the order...
delegate?.orderDidComplete(orderId: "ORD-123")
}
}
class OrderViewController: OrderDelegate {
let manager = OrderManager()
init() {
manager.delegate = self
}
func orderDidComplete(orderId: String) {
print("Order \(orderId) completed!")
}
}
Broadcasts messages across the app using NotificationCenter:
// Post
NotificationCenter.default.post(
name: NSNotification.Name("UserLoggedIn"),
object: nil,
userInfo: ["userId": "123"])
// Observe
NotificationCenter.default.addObserver(
self,
selector: #selector(handleLogin),
name: NSNotification.Name("UserLoggedIn"),
object: nil)
Observes property changes on objects:
class MyObject: NSObject {
@objc dynamic var value: Int = 0
}
// Observe
observation = object.observe(\.value, options: [.new]) {
object, change in
print("New value: \(change.newValue ?? 0)")
}