可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I currently have the following line of code in one of my apps. It is a simple UIAlertView
. However, as of iOS 8, this is now deprecated:
let alertView = UIAlertView(title: "Oops!", message: "This feature isn't available right now", delegate: self, cancelButtonTitle: "OK")
How do I update this to work with iOS 8+? I believe I have to change something to UIAlertCotroller
, though I'm not too sure what.
回答1:
You need to use UIAlertController
instead. To class documentation is pretty straightforward, even containing an usage example in Listing 1 at the very beginning of the doc (sure it's in ObjC and not in Swift but it's quite similar).
So for your use case, here is how it translates to (with added comments):
let alert = UIAlertController(title: "Oops!", message:"This feature isn't available right now", preferredStyle: .alert)
let action = UIAlertAction(title: "OK", style: .default) { _ in
// Put here any code that you would like to execute when
// the user taps that OK button (may be empty in your case if that's just
// an informative alert)
}
alert.addAction(action)
self.presentViewController(alert, animated: true){}
So the compact code will look like:
let alert = UIAlertController(title: "Oops!", message:"This feature isn't available right now", preferredStyle: .Alert)
alert.addAction(UIAlertAction(title: "OK", style: .Default) { _ in })
self.present(alert, animated: true){}
Where self
here is supposed to be your UIViewController
.
Additional tip: if you need to call that code that displays the alert outside of the context of an UIViewController
, (where self
is not an UIViewController
) you can always use the root VC of your app:
let rootVC = UIApplication.sharedApplication().keyWindow?.rootViewController
rootVC?.presentViewController(alert, animated: true){}
(But in general it's preferable to use a known UIViewController
when you have one — and you generally present alerts from UIViewControllers anyway — or try to get the most suitable one depending on your context instead of relying on this tip)
回答2:
For those wondering on how to do this in Objective-C:
//Step 1: Create a UIAlertController
UIAlertController *myAlertController = [UIAlertController alertControllerWithTitle:@"MyTitle"
message: @"MyMessage"
preferredStyle:UIAlertControllerStyleAlert ];
//Step 2: Create a UIAlertAction that can be added to the alert
UIAlertAction* ok = [UIAlertAction
actionWithTitle:@"OK"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
//Do some thing here, eg dismiss the alertwindow
[myAlertController dismissViewControllerAnimated:YES completion:nil];
}];
//Step 3: Add the UIAlertAction ok that we just created to our AlertController
[myAlertController addAction: ok];
//Step 4: Present the alert to the user
[self presentViewController:myAlertController animated:YES completion:nil];
This will pop-up an alert that looks like this:
回答3:
let alertView = UIAlertView(title: "Oops!", message: "This feature isn't available right now", delegate: self, cancelButtonTitle: "OK")
becomes
let alertController = UIAlertController(title: "Oops!", message: "This feature isn't available right now", preferredStyle: .Alert)
let OKAction = UIAlertAction(title: "OK", style: .Default) { (action) in }
alertController.addAction(OKAction)
self.presentViewController(alertController, animated: true) { }
回答4:
I think this is the way to have backward compatibility for older iOS SDK and to use new API when using newer SDK. Also it is without warnings for deprecation in code using deprecated class.
if ([UIAlertController class]) {
// Use new API to create alert controller, add action button and display it
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"CityBoard" message:error.errorDescription preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* ok = [UIAlertAction actionWithTitle: @"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
[alertController dismissViewControllerAnimated:YES completion:nil];
}];
[alertController addAction: ok];
[self presentViewController:alertController animated:YES completion:nil];
} else {
// We are running on old SDK as the new class is not available
// Hide the compiler errors about deprecation and use the class available on older SDK
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"CityBoard"
message:error.errorDescription
delegate:self
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
#pragma clang diagnostic pop
回答5:
Swift 2.0:
Use AlertController.
Example for Action Sheet:
let mediaActionSheet: UIAlertController = UIAlertController(title: "Media Action Sheet", message: "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
}
mediaActionSheet.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
}
mediaActionSheet.addAction(takePictureAction)
//Create and add a second option action
let choosePictureAction: UIAlertAction = UIAlertAction(title: "Choose From Gallery", style: .Default) { action -> Void in
//Code for picking from gallery goes here
}
mediaActionSheet.addAction(choosePictureAction)
//Present the AlertController
self.presentViewController(mediaActionSheet, animated: true, completion: nil)
Example for Alerts:
1)
let simpleAlert = UIAlertController(title: "Simple Alert", message: "It is just awesome", preferredStyle: UIAlertControllerStyle.Alert);
//show it
showViewController(simpleAlert, sender: self);
2) Alert With TextField in it.
let inputTextFieldAlert:UIAlertController = UIAlertController(title: " Input TextField Alert ", message: " Enter on the below TextField ", preferredStyle: UIAlertControllerStyle.Alert);
//default input textField (no configuration...)
inputTextFieldAlert.addTextFieldWithConfigurationHandler(nil);
//no event handler (just close dialog box)
inputTextFieldAlert.addAction(UIAlertAction(title: "No", style: UIAlertActionStyle.Cancel, handler: nil));
//event handler with closure
inputTextFieldAlert.addAction(UIAlertAction(title: "Yes", style: UIAlertActionStyle.Default, handler: {(action:UIAlertAction) in
let fields = inputTextFieldAlert.textFields!;
print("Output: "+fields[0].text!);
}));
presentViewController(inputTextFieldAlert, animated: true, completion: nil);
3)
var alert = UIAlertController(title: "TextField Alert", message: "Enter on the below TextField", preferredStyle: UIAlertControllerStyle.Alert);
//configured input textField
var field:UITextField?;
alert.addTextFieldWithConfigurationHandler({(input:UITextField)in
input.placeholder="Empty Dtaa ;-)";
input.clearButtonMode=UITextFieldViewMode.WhileEditing;
field=input;
});
//YES Handler
func yesHandler(actionTarget: UIAlertAction){
print(field!.text!);
}
//event handler with predefined function
alert.addAction(UIAlertAction(title: "Yes", style: UIAlertActionStyle.Default, handler: yesHandler));
presentViewController(alert, animated: true, completion: nil);
回答6:
The examples above didn't help me much. My solution is for XCode 6.4., Swift 1.2 and you can copy and paste this code in a test project to get a feeling how it works :
SOLUTION 1 - Swift 1.2 :
import UIKit
let ALERT_TITLE = "Got you working, right?"
let ALERT_MESSAGE = "Well maybe..."
class ViewController: UIViewController
{
private var alert: UIAlertController!
private var presentAlertButton: UIButton!
override func viewDidAppear(animated: Bool)
{
/*
// QUICK TEST - 1
self.presentViewController(alert, animated: true, completion: nil)
*/
// QUCIK TEST - 2
/*
let rootVC = UIApplication.sharedApplication().keyWindow?.rootViewController
rootVC?.presentViewController(alert, animated: true, completion: nil)
*/
}
override func viewDidLoad()
{
super.viewDidLoad()
createAndAddAlertV()
createAndAddAlertButton()
}
private func createAndAddAlertV()
{
alert = UIAlertController(title:ALERT_TITLE, message:ALERT_MESSAGE, preferredStyle: .Alert)
let alertAction = UIAlertAction(title: "OK", style: .Default, handler: nil)
alert.addAction(alertAction)
}
private func createAndAddAlertButton()
{
presentAlertButton = UIButton(frame: CGRectMake(
view.frame.size.width / 2,
view.frame.size.height / 2,
200,
100))
presentAlertButton.layer.anchorPoint = CGPointMake(1.0, 1.0)
presentAlertButton.backgroundColor = UIColor.redColor()
presentAlertButton.setTitle("Click For Alert", forState: .Normal)
presentAlertButton.addTarget(self, action: "showAlertV", forControlEvents: .TouchUpInside)
self.view.addSubview(presentAlertButton)
}
@IBAction func showAlertV()
{
println(" Showing... ")
self.presentViewController(alert, animated: true, completion: nil)
}
}
I checked this solution in Xcode 7.0. It worked. Xcode made one change. I recompiled it in Xcode 6.4 again and it worked. The changes for Swift 2.0 should be minor if existent at all.
Hope this helps ;)
回答7:
You can use this code for Alert view :
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Title" message:@"Message" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* ok = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil];
[alertController addAction:ok];
[self presentViewController:alertController animated:YES completion:nil];
For multiple buttons you can use :
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Title" message:@"Message" preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:[UIAlertAction actionWithTitle:@"Button 1" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
[self loadGooglrDrive];
}]];
[alertController addAction:[UIAlertAction actionWithTitle:@"Button 2" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
[self loadDropBox];
}]];
[alertController addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
[self closeAlertview];
}]];
dispatch_async(dispatch_get_main_queue(), ^ {
[self presentViewController:alertController animated:YES completion:nil];
});
-(void)closeAlertview
{
[self dismissViewControllerAnimated:YES completion:nil];
}
回答8:
https://github.com/nagibazad/UIAlertControllerWrapper
This wrapper provides a way of converting UIAlertView to UIAlertController easily. UIAlertView
is deprecated from iOS 9.0
. Convert your UIAlertView
of old projects to UIAlertController
keeping your delegate implementation remain same using this UIAlertControllerWrapper
and get rid of all the UIAlertView
related warnings
.