我正在尝试将数组中的警报操作传递给用于将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。 我已经写了一些快速的新文件,我在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)
如果我没有通过关闭它工作正常,如果通过关闭点击确定它崩溃。 我还发现我们需要复制一个块,当它作为一个集合传递时,我做了那个但是有些东西仍然不对,我无法弄明白。你能告诉我在这里需要做什么吗?
由于
答案 0 :(得分: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)
答案 1 :(得分:-1)
为什么不制作原生的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差异和一些不错的默认设置,因此如果你想在iPhone上进行简单的提醒,你可以viewController.presentAlert(title: "Error", message: "Something broke")
。