How to use UIAlertController to replace UIActionSheet?
I am maintaining an old iOS project which based on SDK 6.0.
A method on this project called
-(void) showComboBox:(UIView*)view:withOptions:(NSDictionary*)options
is used to show a combo box. To achieve the goal, it used UIActionSheet, which is deprecated on iOS8.
My solution is like this:
if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber10_8) {
UIAlertController* alertController = [UIAlertController
alertControllerWithTitle:@"title"
message:@"message"
preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction* item = [UIAlertAction actionWithTitle:@"item"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
//do something here
//inform the selection to the WebView
...
[alertController dismissViewControllerAnimated:YES completion:nil];
}];
UIAlertAction* cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
[alertController dismissViewControllerAnimated:YES completion:nil];
}];
[alertController addAction:item];
[alertController addAction:cancelAction];
//I am not sure whether it's the right way
if ([view.nextResponder isKindOfClass:UIViewController.class]) {
UIViewController* vc = (UIViewController*)view.nextResponder;
[vc presentViewController:alertController animated:YES completion:nil];
}
Is that a proper solution?
This is what I mostly concern about: UIAlertController needs to be added to a UIViewController but I can only get the pointer of the UIView, so I used view.nextResponder to get what I want, but it's that a good way?
Solution 1:
I have used following code to show action sheet using UIAlertViewController
and it works perfect.
Swift
let alert = UIAlertController(title: "Action Title", message: "Action Message", preferredStyle: .actionSheet)
let action = UIAlertAction(title: "Item", style: .default) {
UIAlertAction in
// Write your code here
}
alert.addAction(action)
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) {
UIAlertAction in
// It will dismiss action sheet
}
alert.addAction(cancelAction)
self.present(alert, animated: true, completion: nil)
Objective C
- (IBAction)buttonClicked:(id)sender {
UIAlertController *actionSheet = [UIAlertController alertControllerWithTitle:@"Action Sheet" message:@"Using the alert controller" preferredStyle:UIAlertControllerStyleActionSheet];
[actionSheet addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
// Cancel button tappped.
[self dismissViewControllerAnimated:YES completion:^{
}];
}]];
[actionSheet addAction:[UIAlertAction actionWithTitle:@"Delete" style:UIAlertActionStyleDestructive handler:^(UIAlertAction *action) {
// Distructive button tapped.
[self dismissViewControllerAnimated:YES completion:^{
}];
}]];
[actionSheet addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
// OK button tapped.
[self dismissViewControllerAnimated:YES completion:^{
}];
}]];
// Present action sheet.
[self presentViewController:actionSheet animated:YES completion:nil];
}
Edit:
You need to get UIViewController
object here. You can set global variable or call a delegate method, or you can use notification to get view controller object in this code.
and last line in above code will be like.
[self.viewController presentViewController:actionSheet animated:YES completion:nil];
self.viewController
is a global variable which will be set before you actually get this view.
Because the approach you are following now using view.nextResponder
. I'm afraid that it may not work.
Solution 2:
I have used action sheet for changing profile picture. I followed Kampai approach, just removed dismissviewController call since it was kicking me out of a view when pressing Cancel or photo selection view
UIAlertController *actionSheet = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
[actionSheet addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
// Cancel button tappped do nothing.
}]];
[actionSheet addAction:[UIAlertAction actionWithTitle:@"Take photo" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
// take photo button tapped.
[self takePhoto];
}]];
[actionSheet addAction:[UIAlertAction actionWithTitle:@"Choose photo" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
// choose photo button tapped.
[self choosePhoto];
}]];
[actionSheet addAction:[UIAlertAction actionWithTitle:@"Delete Photo" style:UIAlertActionStyleDestructive handler:^(UIAlertAction *action) {
// Distructive button tapped.
[self deletePhoto];
}]];
Solution 3:
Swift update -
let actionSheet = UIAlertController.init(title: "Please choose a source type", message: nil, preferredStyle: .actionSheet)
actionSheet.addAction(UIAlertAction.init(title: "Take Photo", style: UIAlertActionStyle.default, handler: { (action) in
self.openCamera()
}))
actionSheet.addAction(UIAlertAction.init(title: "Choose Photo", style: UIAlertActionStyle.default, handler: { (action) in
self.showPhotoLibrary()
}))
actionSheet.addAction(UIAlertAction.init(title: "Cancel", style: UIAlertActionStyle.cancel, handler: { (action) in
// self.dismissViewControllerAnimated(true, completion: nil) is not needed, this is handled automatically,
//Plus whatever method you define here, gets called,
//If you tap outside the UIAlertController action buttons area, then also this handler gets called.
}))
//Present the controller
self.present(actionSheet, animated: true, completion: nil)
Solution 4:
Swift 4
let alert = UIAlertController(title: "Select One", message: nil, preferredStyle: UIAlertControllerStyle.actionSheet)
alert.addAction(UIAlertAction(title: "Cancel", style: UIAlertActionStyle.cancel, handler: nil))
alert.addAction(UIAlertAction(title: "Export", style: UIAlertActionStyle.default, handler: { (action) in
// TODO: Export wordlist
}))
alert.addAction(UIAlertAction(title: "Import", style: UIAlertActionStyle.default, handler: { (action) in
// TODO: Import wordlist
}))
self.present(alert, animated: true, completion: nil)