2017-06-05 27 views
0

我試圖將數組中的警報操作傳遞給用於將UIAlertController配置簡化爲一行的函數。 我能夠成功傳遞按鈕標題,但不是警報操作。 這是我正在做的事情。將數組中的閉包/塊作爲參數傳遞iOS

+(void)showAlertWithTitle:(NSString*)title 
        message:(NSString*)alertmessage 
      buttonTitles:(NSArray*)buttonTitles 
      buttonActions:(NSArray*)buttonActions 
     inViewController:(UIViewController*)viewController { 

    UIAlertController *alert = [UIAlertController alertControllerWithTitle:title message:alertmessage preferredStyle:UIAlertControllerStyleAlert]; 

    [buttonTitles enumerateObjectsUsingBlock:^(NSString* buttonTitle,NSUInteger idx,BOOL *stop){ 
     UIAlertAction *action = [UIAlertAction actionWithTitle:buttonTitle style:UIAlertActionStyleDefault handler: [[buttonActions objectAtIndex:idx] copy]]; //blocks should always be copied to heap from stack else they will crash 
     [alert addAction:action]; 
    }]; 

    [viewController presentViewController:alert animated:YES completion:nil]; 

} 

上面的代碼文件寫得很長,所以它在目標c中。 我寫了一些新的文件,這些文件在swift中,我正在用swift調用上面的方法,如下所示。

CommonManager.showAlert(withTitle: "", message: "Feedback Sent", 
     buttonTitles: ["Ok"], buttonActions: [ { (action: UIAlertAction) in 

        print("you pressed Ok alert button"); 

        // call method whatever u need 
       }], in: self) 

如果我沒有通過關閉工作正常,如果通過關閉時點擊確定它崩潰。 我還發現,我們需要複製一個塊,當它作爲一個集合傳遞,我做到了,但有些東西仍然是不正確的,我無法弄清楚。你能告訴我我需要在這裏做什麼嗎?

感謝

回答

-1

而不是處理轉換的怪事,爲什麼不只是做一個原生迅速的版本?

這裏是我的版本相同的功能:

extension UIViewController { 

    func presentAlert(title: String, message: String, actions: [UIAlertAction] = [UIAlertAction(title: "OK", style: .cancel, handler: nil)], iPadOrigin: CGRect? = nil, style: UIAlertControllerStyle = .alert, animated: Bool = true, completion: (() ->())? = nil) { 

     let alert = UIAlertController(title: title, message: message, preferredStyle: style) 
     actions.forEach(alert.addAction) 
     alert.popoverPresentationController?.sourceView = self.view 
     if let iPadOrigin = iPadOrigin { 
      alert.popoverPresentationController?.sourceRect = iPadOrigin 
     } 

     present(alert, animated: animated, completion: completion) 
    } 

    func presentAlert(title: String, message: String, actions: [UIAlertAction] = [UIAlertAction(title: "OK", style: .cancel, handler: nil)], iPadButtonOrigin: UIBarButtonItem? = nil, style: UIAlertControllerStyle = .alert, animated: Bool = true, completion: (() ->())? = nil) { 

     let alert = UIAlertController(title: title, message: message, preferredStyle: style) 
     actions.forEach(alert.addAction) 
     alert.view.tintColor = Color.BlueDarker 
     alert.popoverPresentationController?.barButtonItem = iPadButtonOrigin 

     present(alert, animated: animated, completion: completion) 
    } 
} 

它還處理iPad的分歧和一些不錯的默認值,所以你可能只是做viewController.presentAlert(title: "Error", message: "Something broke"),如果你想在iPhone上一個簡單的警報。

1

問題是Swift閉包是一種與Objective-C塊不同的對象,所以試圖將它作爲塊運行時崩潰。

通常情況下,如果Swift編譯器看到你將一個閉包傳遞給一個帶有塊類型參數的Objective-C方法,它會將Swift閉包轉換爲Objective-C塊,但在這種情況下,它只會看到你把它放在一個數組中,而不是關於數組內部的方法,所以它不會做任何轉換。

我可以計算出,以得到它的工作的唯一辦法是這樣的:

CommonManager.showAlert(withTitle: "", message: "Feedback Sent", 
     buttonTitles: ["Ok"], buttonActions: [ { (action: UIAlertAction) in 

        print("you pressed Ok alert button"); 

        // call method whatever u need 
       } as (@convention(block) (UIAlertAction) -> Void)!], in: self) 
+0

該解決方案爲我工作,謝謝@newacct –