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

Cách kiểm soát chiều rộng/chiều cao Alert Dialog mặc định trong iOS

Mặc định UIAlertController không cho tùy chỉnh width/height. Tuy nhiên có thể dùng NSLayoutConstraint trên alert.view để ép kích thước (chỉ hoạt động tương đối, Apple không khuyến khích).

UIAlertController Docs

Cách ép width/height với NSLayoutConstraint

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

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

Bước 2: Storyboard

Thêm Button "Show Alert" → @IBAction func btnATap(_ sender: Any)

Bước 3: Code ép kích thước


@IBAction func btnATap(_ sender: Any) {
    let alert = UIAlertController(title: "Tiêu đề của bạn", 
                                  message: "Nội dung thông báo dài hơn để test height...", 
                                  preferredStyle: .alert)
    
    // 1. Height constraint
    let heightConstraint = NSLayoutConstraint(
        item: alert.view!,
        attribute: .height,
        relatedBy: .equal,
        toItem: nil,
        attribute: .notAnAttribute,
        multiplier: 1,
        constant: 200 // Chiều cao mong muốn
    )
    alert.view.addConstraint(heightConstraint)
    
    // 2. Width constraint
    let widthConstraint = NSLayoutConstraint(
        item: alert.view!,
        attribute: .width,
        relatedBy: .equal,
        toItem: nil,
        attribute: .notAnAttribute,
        multiplier: 1,
        constant: 300 // Chiều rộng mong muốn
    )
    alert.view.addConstraint(widthConstraint)
    
    // 3. Actions
    alert.addAction(UIAlertAction(title: "Hủy", style: .cancel))
    alert.addAction(UIAlertAction(title: "Xác nhận", style: .default) { _ in
        print("User xác nhận")
    })
    
    // 4. Present
    self.present(alert, animated: true)
}

Cách kiểm soát chiều rộng/chiều cao Alert Dialog mặc định trong iOS

Lưu ý quan trọng & Hạn chế

  • Không ổn định: Apple có thể thay đổi internal view hierarchy bất kỳ lúc nào
  • Chỉ hoạt động trên .alert, không áp dụng cho .actionSheet
  • Content có thể bị cắt (clipped) nếu quá lớn
  • iPad: Alert hiển thị dạng popover, width constraint có thể bị ignore
  • Không thể set max/min width/height - chỉ fixed constraint

Best Practice: Custom Alert Controller (Khuyên dùng)

Thay vì hack system alert, hãy tạo custom view controller presented modally:


class CustomAlertViewController: UIViewController {
    
    // Custom size
    override var preferredContentSize: CGSize {
        return CGSize(width: 300, height: 250)
    }
    
    // Hoặc dùng presentation controller
    init() {
        super.init(nibName: nil, bundle: nil)
        modalPresentationStyle = .popover // hoặc .custom
        modalTransitionStyle = .coverVertical
    }
    
    required init?(coder: NSCoder) { fatalError() }
}

// Hoặc dùng thư viện:
// - SwiftEntryKit (popups, toasts, alerts tùy chỉnh hoàn toàn)
// - PopupDialog
// - SCLAlertView
// - Alertift (Swift wrapper cho UIAlertController)

Khi nào nên custom size?

Trường hợp Khuyên dùng
Alert đơn giản (OK/Cancel) UIAlertController chuẩn
Form nhập liệu phức tạp Custom VC hoặc SwiftEntryKit
Cần width/height cụ thể Custom VC (không hack constraint)
Custom layout, animation Custom VC + Transition Delegate

Kết luận

Có thể ép size UIAlertController bằng NSLayoutConstraint trên alert.view, nhưng không khuyến khích cho production do không ổn định. Nên dùng Custom View Controller presented modally hoặc thư viện popup chuyên dụng.