Customize UIAlertController
Trong iOS, UIAlertView được dùng rất nhiều để hiển thị một message dialog hoặc confirm dialog... Tuy nhiên, từ iOS 8.0 trở đi, UIAlertView đã bị deprecated và thay thế bởi UIAlertController . Giao diện mặc định của UIAlertController nhìn đơn giản nhưng khá đơn điệu, nhiều khi không đáp ứng ...
Trong iOS, UIAlertView được dùng rất nhiều để hiển thị một message dialog hoặc confirm dialog... Tuy nhiên, từ iOS 8.0 trở đi, UIAlertView đã bị deprecated và thay thế bởi UIAlertController. Giao diện mặc định của UIAlertController nhìn đơn giản nhưng khá đơn điệu, nhiều khi không đáp ứng được yêu cầu đưa ra. Vì vậy, trong bài viết này, chúng ta sẽ cùng tìm hiểu một số cách đơn giản để customize giao diện mặc định của Apple.
Đơn giản là lấy ra backgroundView của UIAlertController rồi set backgroundColor và cornerRadius cho nó.
fileprivate func customizeBackground() { let alertController = UIAlertController(title: "Vietcombank", message: "Số dư tài khoản của bạn là 13.015 VNĐ", preferredStyle: .alert) let okAction = UIAlertAction(title: "OK", style: .default, handler: nil) alertController.addAction(okAction) // Get background view let backgroundView = alertController.view.subviews.last?.subviews.last backgroundView?.layer.cornerRadius = 14.0 backgroundView?.backgroundColor = .purple present(alertController, animated: true, completion: nil) }
Sử dụng NSMutableAttributedString để tạo custom title, custom message, customActionTitle và setValue cho các private property của UIAlertController: attributedTitle, attributedMessage, titleTextColor.
fileprivate func customizeFont() { let alertController = UIAlertController(title: nil, message: nil, preferredStyle: .alert) let okAction = UIAlertAction(title: "Nhận thưởng ngay", style: .default, handler: nil) alertController.addAction(okAction) // Create custom title let customTitle = NSMutableAttributedString(string: "Vietlott thông báo", attributes: [ NSFontAttributeName: UIFont(name: "Times New Roman", size: 24.0)!, NSForegroundColorAttributeName: UIColor.red ]) alertController.setValue(customTitle, forKey: "attributedTitle") // Create custom message let customMessage = NSMutableAttributedString(string: " Chúc mừng bạn đã trúng giải Jackpot với giá trị giải thưởng. ", attributes: [ NSFontAttributeName: UIFont(name: "Times New Roman", size: 18.0)!, NSForegroundColorAttributeName: UIColor.blue ]) customMessage.append(NSMutableAttributedString(string: "112.000.000.000 VNĐ", attributes: [ NSFontAttributeName: UIFont(name: "Georgia", size: 14.0)!, NSForegroundColorAttributeName: UIColor.black ])) alertController.setValue(customMessage, forKey: "attributedMessage") // Change action title color okAction.setValue(UIColor.orange, forKey: "titleTextColor") present(alertController, animated: true, completion: nil) }
Dùng private property contentViewController có thể giúp ta thêm một view controller vào trong UIAlertController. Đồng nghĩa có thể giúp ta thực hiện các yêu cầu phức tạp hơn, ví dụ, thêm list item, ảnh, tableview... các giao diện phức tạp hơn vào UIAlertController. Let's do it.
Tạo một UIViewController mới, set size XIB thành Freeform, awidth = 270, rồi design theo tuỳ ý. Ví dụ như CustomViewController hiển thị list item như sau: Code:
import UIKit class CustomViewController: UIViewController { @IBOutlet fileprivate weak var imageView: UIImageView! @IBOutlet fileprivate weak var messageLabel: UILabel! @IBOutlet fileprivate weak var tableView: UITableView! @IBOutlet fileprivate weak var tableViewHeightConstraint: NSLayoutConstraint! fileprivate var items = [(String, Bool)]() override func viewDidLoad() { super.viewDidLoad() tableView.register(UINib(nibName: "ItemTableViewCell", bundle: nil), forCellReuseIdentifier: "ItemCell") } func updateUI(image: String, message: String, items: [(String, Bool)]) { imageView?.image = UIImage(named: image) messageLabel?.text = message self.items = items tableViewHeightConstraint?.constant = 44.0 * CGFloat(items.count) tableView?.reloadData() } } // MARK: - UITableViewDataSource extension CustomViewController: UITableViewDataSource { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return items.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { guard let cell = tableView.dequeueReusableCell(withIdentifier: "ItemCell", for: indexPath) as? ItemTableViewCell else { return UITableViewCell() } cell.updateUI(item: items[indexPath.row]) return cell } }
Và một cell rất đơn giản giản, chỉ có 1 label và 1 switch.
class ItemTableViewCell: UITableViewCell { @IBOutlet fileprivate weak var titleLabel: UILabel! @IBOutlet fileprivate weak var `switch`: UISwitch! func updateUI(item: (String, Bool)) { titleLabel.text = item.0 `switch`.isOn = item.1 } }
Bây giờ, để customize UIAlertController bằng một UIViewController, ta chỉ cần setValue cho key contentViewController. Và cũng đừng quên set data cho custom viewController mới tạo nhé.
fileprivate func customizeViewController() { let alertController = UIAlertController(title: nil, message: nil, preferredStyle: .alert) let okAction = UIAlertAction(title: "OK", style: .default, handler: nil) alertController.addAction(okAction) // Create custom content viewController let contentViewController = CustomViewController() contentViewController.preferredContentSize = contentViewController.view.bounds.size alertController.setValue(contentViewController, forKey: "contentViewController") contentViewController.updateUI(image: "heart", message: "Tiêu chuẩn chọn người yêu của bạn là gì?", items: [ ("Xinh đẹp", false), ("Sexy", false), ("Giỏi giang", false), ("Dịu dàng", false), ("Biết nấu ăn", true), ("Là con gái", true), ]) present(alertController, animated: true, completion: nil) }
Kết quả là chúng ta sẽ có một alert controller chứa image, text, tableView được customize như sau: