在哪里可以找到关于Swift警报(UIAlertController)的清晰解释?

21

我找不到一个清晰明了的解释。


6
Stack Overflow的格式要求必须提出问题。如果你想回答自己的问题,可以这样做,但你必须先提出一个问题。将你的帖子重新格式化为你试图寻找答案的问题形式,然后将上面的帖子移动到答案中。 - vacawama
你可以使用 UIAlertController 来创建警告框和操作表。我发现示例是理解事物如何工作的最简单方法。这里有一个警告框示例和一个操作表示例 - Suragch
3个回答

64

在搜索一个主题一段时间后,我没有找到清晰的解释,即使在它的类参考UIAlertController 参考中也是如此。

虽然还可以,但对我来说不够清晰。

所以,在收集了一些信息后,我决定自己做出解释(希望能有所帮助)。

接下来就是解释:

  1. UIAlertView已经取消使用了: Swift 中的 UIAlertView
  2. UIAlertController应该在iOS8+中使用。要创建一个,首先需要实例化它,构造函数(init)有3个参数:

2.1 title:String -> 在警告对话框顶部显示的大号粗体文本

2.2 message:String -> 较小的文本(基本上是解释它自己的)

2.3 prefferedStyle:UIAlertControllerStyle -> 定义对话框样式,在大多数情况下:UIAlertControllerStyle.Alert

  1. 现在要向用户展示它,我们可以使用showViewControllerpresentViewController并将我们的警报作为参数传递

  2. 要与用户进行一些交互,我们可以使用:

4.1 UIAlertController.addAction来创建按钮

4.2 UIAlertController.addTextField来创建文本字段

编辑说明:下面的代码示例已更新为Swift 3语法。

示例1:简单对话框

@IBAction func alert1(sender: UIButton) {
     //simple alert dialog
    let alert=UIAlertController(title: "Alert 1", message: "One has won", preferredStyle: UIAlertControllerStyle.alert);
    //show it
    show(alert, sender: self);
}

示例2: 具有一个输入文本框和两个按钮的对话框

@IBAction func alert2(sender: UIButton) {
    //Dialog with one input textField & two buttons
    let alert=UIAlertController(title: "Alert 2", message: "Two will win too", preferredStyle: UIAlertControllerStyle.alert);
    //default input textField (no configuration...)
    alert.addTextField(configurationHandler: nil);
    //no event handler (just close dialog box)
    alert.addAction(UIAlertAction(title: "No", style: UIAlertActionStyle.cancel, handler: nil));
    //event handler with closure
    alert.addAction(UIAlertAction(title: "Yes", style: UIAlertActionStyle.default, handler: {(action:UIAlertAction) in
        let fields = alert.textFields!;
        print("Yes we can: "+fields[0].text!);
    }));
    present(alert, animated: true, completion: nil);
}

示例 3: 一个自定义输入文本框和一个按钮

@IBAction func alert3(sender: UIButton) {
   // one input & one button
   let alert=UIAlertController(title: "Alert 3", message: "Three will set me free", preferredStyle: UIAlertControllerStyle.alert);

    //configured input textField
    var field:UITextField?;// operator ? because it's been initialized later
    alert.addTextField(configurationHandler:{(input:UITextField)in
        input.placeholder="I am displayed, when there is no value ;-)";
        input.clearButtonMode=UITextFieldViewMode.whileEditing;
        field=input;//assign to outside variable(for later reference)
    });
    //alert3 yesHandler -> defined in the same scope with alert, and passed as event handler later
    func yesHandler(actionTarget: UIAlertAction){
        print("YES -> !!");
        //print text from 'field' which refer to relevant input now
        print(field!.text!);//operator ! because it's Optional here
    }
    //event handler with predefined function
    alert.addAction(UIAlertAction(title: "Yes", style: UIAlertActionStyle.default, handler: yesHandler));

    present(alert, animated: true, completion: nil);
 }

希望这能有所帮助,祝你好运 ;-)


2
我很高兴你分享了你所学到的东西!非常感谢你提供逐步解释。志同道合 ;) - swiftBoy
我正在使用Xcode 7.3.1并在iOS9上进行测试。当使用第一个示例中的showViewController(alert,sender:self)与UINavigationController一起使用(不包括它的ok)时,我会得到奇怪的行为。它将警报视图添加到导航栏中。使用self.presentViewController(alert,animated:true,completion:nil)可以正常工作。 - pls
是的,我也注意到了这一点,似乎是由于这些方法之间的差异导致的:showViewController _将vc类推到导航栈上,方式与pushViewController类似_,但presentViewController _以模态方式显示视图控制器在当前视图控制器上面_。 - Nikita Kurtin
1
谢谢你提供的有用信息,但是你确定在Swift中需要分号吗? - Ethan Parker
@EthanParker 与许多其他编程语言不同,Swift 不要求您在代码中的每个语句后面写分号 (;),尽管如果您愿意,可以这样做。 我个人更喜欢跨语言的代码风格,因此您可以在我的示例中看到它。 - Nikita Kurtin

11

使用presentViewController:animated:completion:方法,可以将UIAlertController实例模态地呈现在屏幕上,就像任何其他UIViewController一样。当创建它时,使UIAlertController实例在作为ActionSheet或AlertView工作不同的是您传递的样式参数。

无需再使用代理

如果你使用过UIActionSheet或UIAlertView,那么你应该知道获取回调的方法是让类(在大多数情况下是ViewController)实现UIActionSheetDelegate或UIAlertViewDelegate协议。有一些开源项目用块回调代替了这种委托模式,但官方API从未更新过。UIAlertController不使用代理。相反,它有一系列UIAlertAction项,使用闭包(或如果您使用Objective-C,则使用块)来处理用户输入。

对于Action Sheet

@IBAction func showActionSheet(sender: AnyObject) {
  //Create the AlertController
  let actionSheetController: UIAlertController = UIAlertController(title: "Action Sheet", message: "Swiftly Now! Choose an option!", preferredStyle: .ActionSheet)

  //Create and add the Cancel action
  let cancelAction: UIAlertAction = UIAlertAction(title: "Cancel", style: .Cancel) { action -> Void in
    //Just dismiss the action sheet
  }
  actionSheetController.addAction(cancelAction)
    //Create and add first option action
  let takePictureAction: UIAlertAction = UIAlertAction(title: "Take Picture", style: .Default) { action -> Void in
    //Code for launching the camera goes here
    }
  actionSheetController.addAction(takePictureAction)
  //Create and add a second option action
  let choosePictureAction: UIAlertAction = UIAlertAction(title: "Choose From Camera Roll", style: .Default) { action -> Void in
    //Code for picking from camera roll goes here
    }
  actionSheetController.addAction(choosePictureAction)

  //Present the AlertController
  self.presentViewController(actionSheetController, animated: true, completion: nil)
}

关于带有文本框的AlertView

@IBAction func showAlert(sender: AnyObject) {
  //Create the AlertController
  let actionSheetController: UIAlertController = UIAlertController(title: "Alert", message: "Swiftly Now! Choose an option!", preferredStyle: .Alert)

  //Create and add the Cancel action
  let cancelAction: UIAlertAction = UIAlertAction(title: "Cancel", style: .Cancel) { action -> Void in
    //Do some stuff
    }
  actionSheetController.addAction(cancelAction)
    //Create and an option action
  let nextAction: UIAlertAction = UIAlertAction(title: "Next", style: .Default) { action -> Void in
    //Do some other stuff
    }
  actionSheetController.addAction(nextAction)
  //Add a text field
  actionSheetController.addTextFieldWithConfigurationHandler { textField -> Void in
       //TextField configuration
     textField.textColor = UIColor.blueColor()
   }

   //Present the AlertController
   self.presentViewController(actionSheetController, animated: true, completion: nil)
}

谢谢你的贡献,即使我半年前已经回答了它。仍然是非常好的答案,所以我很高兴地投了赞成票 ;-) 顺便说一句,你也可以使用showViewController方法显示警报 - 灵活性较小,但在不需要完成时有意义。 - Nikita Kurtin

1
一些语法与原始响应不同。以下是一些示例代码,如果用户未登录iCloud,则会向其发出警报。
CKContainer.default().accountStatus { (accountStatus, error) in
        switch accountStatus {
        case .available:
            print("iCloud Available")
        case .noAccount:
            print("No iCloud account")
            //simple alert dialog
            let alert=UIAlertController(title: "Sign in to iCloud", message: "This application requires iClound. Sign in to your iCloud account to write records. On the Home screen, launch Settings, tap iCloud, and enter your Apple ID. Turn iCloud Drive on. If you don't have an iCloud account, tap Create a new Apple ID", preferredStyle: UIAlertControllerStyle.alert);
            //no event handler (just close dialog box)
            alert.addAction(UIAlertAction(title: "Cancel", style: UIAlertActionStyle.cancel, handler: nil));
            //show it
            self.present(alert, animated: true, completion: nil)
        case .restricted:
            print("iCloud restricted")
        case .couldNotDetermine:
            print("Unable to determine iCloud status")
        }
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接