Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> iOS

Cách hiển thị Alert Dialog trong iOS (UIAlertController)

UIAlertController là cách chuẩn hiển thị alert, action sheet trong iOS. Thay thế UIAlertView và UIActionSheet (deprecated).

Apple Docs UIAlertController

3 Bước cơ bản

  1. Tạo UIAlertController với title, message, style
  2. Thêm UIAlertAction (nút bấm)
  3. Present alert: present(alert, animated: true)

Ví dụ cơ bản

Bước 1: Tạo dự án

Xcode → Single View App → Tên: "Alert".

Bước 2: Storyboard

Thêm Button "Show Alert" → Tạo @IBAction func tap(_ sender: Any)

Bước 3: Code Alert


@IBAction func tap(_ sender: Any) {
    // 1. Tạo alert
    let alert = UIAlertController(
        title: "Chào mừng",
        message: "Chào mừng đến với kênh của tôi. Cảm ơn đã xem.\nNhấn OK để tiếp tục",
        preferredStyle: .alert // .actionSheet cho bottom sheet
    )
    
    // 2. Thêm action
    let okAction = UIAlertAction(title: "OK", style: .default) { _ in
        print("User nhấn OK")
    }
    alert.addAction(okAction)
    
    // 3. Present
    self.present(alert, animated: true, completion: nil)
}

Bước 4: Chạy app

Cách hiển thị Alert Dialog trong iOS (UIAlertController)

Các Style Alert

Style Mô tả Dùng khi
.alert Popup giữa màn hình, modal Cảnh báo, xác nhận, nhập liệu ngắn
.actionSheet Bottom sheet từ dưới lên Menu lựa chọn, share, confirm destructive

Action Styles

Style Hiển thị Dùng cho
.default Text bình thường Action chính, OK, Confirm
.cancel Text đậm, thường ở dưới cùng Hủy, Dismiss
.destructive Text đỏ Xóa, Logout, Dangerous action

Alert với Text Field (Input)


let alert = UIAlertController(title: "Đổi tên", message: "Nhập tên mới", preferredStyle: .alert)

alert.addTextField { textField in
    textField.placeholder = "Tên mới"
    textField.keyboardType = .default
}

let saveAction = UIAlertAction(title: "Lưu", style: .default) { _ in
    let newName = alert.textFields?.first?.text ?? ""
    print("Tên mới: \(newName)")
}

let cancelAction = UIAlertAction(title: "Hủy", style: .cancel)
alert.addAction(saveAction)
alert.addAction(cancelAction)

present(alert, animated: true)

Action Sheet (iPad cần sourceView)


let actionSheet = UIAlertController(title: "Chọn hành động", message: nil, preferredStyle: .actionSheet)

actionSheet.addAction(UIAlertAction(title: "Chụp ảnh", style: .default) { _ in
    // Mở camera
})
actionSheet.addAction(UIAlertAction(title: "Chọn từ thư viện", style: .default) { _ in
    // Mở photo library
})
actionSheet.addAction(UIAlertAction(title: "Hủy", style: .cancel))

// iPad: BẮT BUỘC set popoverPresentationController
if let popover = actionSheet.popoverPresentationController {
    popover.sourceView = self.view
    popover.sourceRect = CGRect(x: view.bounds.midX, y: view.bounds.midY, width: 0, height: 0)
    popover.permittedArrowDirections = []
}

present(actionSheet, animated: true)

Extension tiện ích (Quick Alert)


extension UIViewController {
    func showAlert(title: String, message: String, actions: [UIAlertAction] = []) {
        let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
        if actions.isEmpty {
            alert.addAction(UIAlertAction(title: "OK", style: .default))
        } else {
            actions.forEach { alert.addAction($0) }
        }
        present(alert, animated: true)
    }
    
    func showConfirm(title: String, message: String, confirmTitle: String = "OK", 
                     destructive: Bool = false, completion: @escaping (Bool) -> Void) {
        let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
        let confirmStyle: UIAlertAction.Style = destructive ? .destructive : .default
        alert.addAction(UIAlertAction(title: confirmTitle, style: confirmStyle) { _ in completion(true) })
        alert.addAction(UIAlertAction(title: "Hủy", style: .cancel) { _ in completion(false) })
        present(alert, animated: true)
    }
}

// Usage
showConfirm(title: "Xóa?", message: "Bạn chắc chắn?", confirmTitle: "Xóa", destructive: true) { confirmed in
    if confirmed { deleteItem() }
}

Lưu ý

  • Luôn present trên main thread (dispatchQueue.main.async nếu gọi từ background)
  • iPad + ActionSheet: Bắt buộc set popoverPresentationController.sourceView
  • Không thể customize giao diện alert gốc (font, color, layout) - cần custom view controller nếu muốn
  • iOS 13+: preferredStyle: .alert trên iPad cũng hiển thị dạng popup (không còn fullscreen)