2015-04-14 24 views
16

Tôi có các bộ điều khiển khác nhau trong ứng dụng mà tất cả đều yêu cầu xác thực và khi xác thực không thành công, tôi muốn hiển thị cảnh báo có lỗi. Có một số mô hình thiết kế/thực hành tốt nhất để thực hiện việc này không? Tôi có thể chỉ cần tạo một hàm tĩnh trong lớp Trình trợ giúp như sau:Swift Displaying Alerts best practices

static func displayAlert(message: String, buttonTitle: String, vc: UIViewController) 
{ 
    let alertController = UIAlertController(title: "", message: message, preferredStyle: .Alert) 

    let OKAction = UIAlertAction(title: buttonTitle, style: .Default, handler: nil) 
    alertController.addAction(OKAction) 

    vc.presentViewController(alertController, animated: true, completion: nil) 
} 

Nhưng sau đó tôi cần phải vượt qua bộ điều khiển chế độ xem .. có vẻ như thực hành không tốt. Tôi có thể bắn một thông báo và quan sát nó, nhưng điều đó có vẻ như quá mức cần thiết. Tôi có bị lật đổ điều này không, hoặc có cách nào chấp nhận được hơn để xử lý một cái gì đó như thế này?

+1

chuyển trong trình điều khiển chế độ xem ở đây tốt hơn, tốt hơn thực hiện trong trình điều khiển chế độ xem và không thể chia sẻ mã. Tôi sẽ nói rằng bạn đang overthinking nó :) –

Trả lời

36

tôi đã kết thúc việc tạo ra một phần mở rộng cho UIViewController và tạo ra các chức năng cảnh báo có:

extension UIViewController { 

    func alert(message: String, title: String = "") { 
    let alertController = UIAlertController(title: title, message: message, preferredStyle: .Alert) 
    let OKAction = UIAlertAction(title: "OK", style: .Default, handler: nil) 
    alertController.addAction(OKAction) 
    self.presentViewController(alertController, animated: true, completion: nil) 
    } 

} 
1

Tại sao không tạo ra một chức năng tiện ích mà trả về AlertView đến ViewController?

self.presentViewController(Utilities.createAlertController("errorMessage"), animated: true, completion: nil); 
+1

Tôi chỉ không muốn lộn xộn lên tập tin Utils của tôi khi nó có ý nghĩa để sử dụng một phần mở rộng. Có lẽ nó không làm cho cảm giác 100% trong trường hợp này nhưng tôi thích thực tế là tất cả những gì tôi phải làm là gõ alert ("message") từ bất kỳ viewcontroller nào với câu trả lời của tôi. –

+1

Đủ công bằng ... Tôi đoán đó là loại tiện lợi – MobileMon

7

Như câu trả lời ban đầu từ itstrueimryan tại https://stackoverflow.com/a/30714429/6822183

Cập nhật cho Swift 3:

extension UIViewController { 

    func alert(message: String, title: String = "") { 
     let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert) 
     let OKAction = UIAlertAction(title: "OK", style: .default, handler: nil) 
     alertController.addAction(OKAction) 
     self.present(alertController, animated: true, completion: nil) 
    } 
} 
0

Tôi có thể tìm thấy một câu trả lời tốt hơn cho vấn đề này, qua một bài viết của Krakendev: https://krakendev.io/blog/subclassing-can-suck-and-heres-why.

Ý tưởng là để sử dụng lập trình giao thức định hướng để tạo ra một thực hiện mặc định của một cảnh báo chỉ dành riêng cho UIViewControllers:

protocol Alertable { 
    func issueAlert() 
} 

extension Alertable where Self: UIViewController { 
    func issueAlert() { 
     // alert code here 
    } 
} 

Bây giờ, chỉ cần như thế, mỗi UIViewController rằng tuân thủ Alertable sẽ có issueAlert() phương pháp có sẵn cho họ mà không cần phải xác định việc triển khai của chính nó.

Và, tất nhiên, chúng ta có thể xác định các tham số cho hàm issueAlert cũng như:

extension Alertable where Self: UIViewController { 
    func issueAlert(title: "Default Title", message: String = "Default Message") { 
     // alert code here 
    } 
} 

Vì vậy, điều khiển điểm của chúng tôi có thể làm một trong hai:

issueAlert() 

hoặc

issueAlert(title: "Error", message: "Something went wrong") 

Hai ưu điểm của phương pháp này mà tôi có thể nghĩ là bạn biết liệu một bộ điều khiển xem có quyền truy cập vào điều này hay không hod chỉ bằng cách nhìn vào giao thức Alertable trong định nghĩa lớp và các bộ điều khiển xem riêng lẻ có thể ghi đè phương thức này nếu chúng muốn cung cấp chức năng tùy chỉnh. Tất nhiên, bây giờ bạn cũng có thể chỉ định hợp đồng Alertable như một tham số phương thức.

+1

Tôi biết là hơi muộn nhưng KHÔNG. Điều này rất có thể là cách tiếp cận tồi tệ nhất và bài viết bạn đăng tải hoàn tất không cho các ứng dụng/hệ thống lớn. Trong trường hợp này, bạn mong đợi nhà phát triển sẽ tìm kiếm tất cả các lớp trình điều khiển xem và nối thêm 'Alertable' vào chúng và mong các nhà phát triển khác làm như vậy hoàn toàn không được chấp nhận. Vấn đề tiếp theo là một khi bạn sẽ thực hiện các hộp thoại tùy chỉnh, bạn sẽ cần phải kiểm tra cho bộ điều khiển hàng đầu ví dụ 'navigationController ?? self' mà bây giờ phá hủy việc sử dụng giao thức của bạn. Cách dễ nhất là tạo phần mở rộng UIViewController, tốt nhất là những gì OP đã làm. –

+0

Tôi là OP, vừa mới suy đoán về các giải pháp khác. Nhưng công ty cho những suy nghĩ về điều này. Bạn có thể xây dựng trên điểm thứ hai (navigationController) không? Cảm ơn. –

+0

Phần điều khiển chuyển hướng trở thành vấn đề khi/nếu bạn tìm ra giải pháp tốt nhất để sử dụng hộp thoại tùy chỉnh, hãy sử dụng chúng làm chế độ xem và thêm chúng làm chế độ xem (sử dụng bộ điều khiển xem con dường như hoạt động tốt nhất). Trong trường hợp của tôi, tôi sẽ gọi 'viewController.attachDialog (" message ")' hiển thị hộp thoại trong bộ điều khiển xem đã cho và rất tuyệt (hoạt động cho màn hình chia cũng vì nó không được trình bày). Nhưng sau đó nếu tôi làm điều này trong điều khiển chuyển hướng thanh sẽ không được phủ lên. Vì vậy, tôi cần phải gọi 'viewController.navigationController? .attachDialog (" message ")' mà bây giờ phá hủy công cụ chung ... –

0

cập nhật cho nhanh 3:

nếu bạn muốn hiển thị thông báo cảnh báo để người dùng sử dụng bên dưới dòng code đơn giản;

// chức năng, định nghĩa:

func showMessageToUser(title: String, msg: String) { 
    let alert = UIAlertController(title: title, message: msg, preferredStyle: UIAlertControllerStyle.alert) 
    alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.default, handler: nil)) 
    self.present(alert, animated: true, completion: nil) 
} 

// gọi hàm:

self.showMessageToUser(title: "Alert", msg: "your message to user") 

// Thưởng thức mã hóa ..!

7

Swift 4

Đây là tôi muốn điều này vì vậy tôi đã thực hiện mở rộng đầy đủ. Vì vậy, tạo một tập tin nhanh chóng mới trong tên dự án của bạn nó bao giờ bạn thích ở bên nó đặt mã sau đây.

import UIKit 

extension UIViewController { 

    func presentAlertWithTitle(title: String, message: String, options: String..., completion: @escaping (Int) -> Void) { 
     let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert) 
     for (index, option) in options.enumerated() { 
      alertController.addAction(UIAlertAction.init(title: option, style: .default, handler: { (action) in 
       completion(index) 
      })) 
     } 
     self.present(alertController, animated: true, completion: nil) 
    } 
} 

Sau đó, để sử dụng nó mà rất nhiều người không thực sự hiển thị có thể dẫn đến sự nhầm lẫn cho một newbie như bản thân mình.

presentAlertWithTitle(title: "Test", message: "A message", options: "1", "2") { (option) in 
    print("option: \(option)") 
    switch(option) { 
     case 0: 
      print("option one") 
      break 
     case 1: 
      print("option two") 
     default: 
      break 
    } 
}