簡體   English   中英

將數組中的閉包/塊作為參數iOS傳遞

[英]Passing closure/ blocks in array as parameter iOS

我正在嘗試將數組中的警報操作傳遞給一個函數,該函數用於將UIAlertController配置簡化為一行。 能夠成功傳遞按鈕標題,但不能傳遞警報動作。 這是我在做什么。

+(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中。 我已經編寫了一些新文件,它們正在迅速運行,我正在如下快速調用上述方法。

 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)

如果我不通過閉包,它工作正常,如果在單擊“確定”時通過閉包,它將崩潰。 我還發現,當一個塊作為一個集合傳遞時,我們需要復制一個塊,但是我做到了,但是仍然有些不對勁,無法弄清楚。 你能告訴我我在這里需要做什么。

謝謝

問題在於,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)

與其處理轉換的怪異性,不如制作原生的swift版本?

這是我相同功能的版本:

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上發出簡單的警報,可以執行viewController.presentAlert(title: "Error", message: "Something broke")

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM