I'm using objective-c write about UIAlertControllerStyleActionSheet of UIAlertcontroller.
I want to show alert sheet on the iPhone, and popoverPresentationController on the iPad.
First, I have set the UIPopoverPresentationControllerDelegate delegate.
When I click my button, the pop over have show is correct.
But I click on the screen dismiss the popover. it will show below warning.
[Warning] <_UIPopoverBackgroundVisualEffectView 0x14be52ef0> is being asked to animate its opacity. This will cause the effect to appear broken until opacity returns to 1.
Now When I click the button show the pop view again.
It will crash show below log.
Terminating app due to uncaught exception 'NSGenericException', reason: 'Your application has presented a UIAlertController () of style UIAlertControllerStyleActionSheet. The modalPresentationStyle of a UIAlertController with this style is UIModalPresentationPopover. You must provide location information for this popover through the alert controller's popoverPresentationController. You must provide either a sourceView and sourceRect or a barButtonItem. If this information is not known when you present the alert controller, you may provide it in the UIPopoverPresentationControllerDelegate method -prepareForPopoverPresentation.'
*** First throw call stack:
(0x18d9a41c0 0x18c3dc55c 0x19418a8b0 0x193ac60a8 0x193ac3df4 0x193a08d0c 0x1939faac0 0x19376a22c 0x18d9517dc 0x18d94f40c 0x18d94f89c 0x18d87e048 0x18f2ff198 0x1937e2b50 0x1937dd888 0x10011198c 0x18c8605b8)
libc++abi.dylib: terminating with uncaught exception of type NSException
Have anyone know how to resolve the problem?
My code is below:
#interface ViewController () <...UITextViewDelegate,UITextFieldDelegate...> {
UIAlertController *alertTypeAlertController;
UIAlertAction *alertType1Action;
UIAlertAction *alertType2Action;
UIPopoverPresentationController *popPresenter;
}
- (void)viewDidLoad {
[super viewDidLoad];
alertTypeAlertController = [UIAlertController
alertControllerWithTitle:#"selecte one:"
message:nil
preferredStyle:UIAlertControllerStyleActionSheet];
alertType1Action = [UIAlertAction
actionWithTitle:#"Type1"
style:UIAlertActionStyleDefault
handler:nil];
alertType2Action = [UIAlertAction
actionWithTitle:#"Type2"
style:UIAlertActionStyleDefault
handler:nil];
[alertTypeAlertController addAction: alertType1Action];
[alertTypeAlertController addAction: alertType2Action];
// for ipad
popPresenter = [alertTypeAlertController popoverPresentationController];
popPresenter.permittedArrowDirections = UIPopoverArrowDirectionLeft;
popPresenter.delegate = self;
popPresenter.sourceView = self.theTypeBtn;
popPresenter.sourceRect = CGRectMake(230, 22, 10, 10);
....
}
- (void)popoverPresentationControllerDidDismissPopover:(UIPopoverPresentationController *)popoverPresentationController {
// called when a Popover is dismissed
}
- (BOOL)popoverPresentationControllerShouldDismissPopover:(UIPopoverPresentationController *)popoverPresentationController {
// return YES if the Popover should be dismissed
// return NO if the Popover should not be dismissed
return YES;
}
-(UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller {
return UIModalPresentationNone;
}
enter code here
Thank you very much.
Maybe the UIAlertController and UIPopoverPresentationController objects strongly referenced by the ViewController object which makes
the Popover can't release after you dismiss it.
I later found your problem is that you try to create popPresenter
once in the viewDidLoad method and present it every time you touch
the button,you should create a new one instead,you can move the ViewDidLoad code to a new method,and call it by touch event, fix like this:
- (void)makePopover
{
alertTypeAlertController = [UIAlertController
alertControllerWithTitle:#"selecte one:"
message:nil
preferredStyle:UIAlertControllerStyleActionSheet];
alertType1Action = [UIAlertAction
actionWithTitle:#"Type1"
style:UIAlertActionStyleDefault
handler:nil];
alertType2Action = [UIAlertAction
actionWithTitle:#"Type2"
style:UIAlertActionStyleDefault
handler:nil];
[alertTypeAlertController addAction: alertType1Action];
[alertTypeAlertController addAction: alertType2Action];
// for ipad
popPresenter = [alertTypeAlertController popoverPresentationController];
popPresenter.permittedArrowDirections = UIPopoverArrowDirectionLeft;
popPresenter.canOverlapSourceViewRect = YES; // adding this line
popPresenter.delegate = self;
popPresenter.sourceView = self.theTypeBtn;
popPresenter.sourceRect = CGRectMake(230, 22, 10, 10);
}
- (IBAction)touchButton:(id)sender {
[self makePopover];
[self presentViewController:alertTypeAlertController animated:YES completion:nil];
}
I am just modifying your code, please check if it is working or not.
- (IBAction)actionButton:(UIButton*)sender {
alertTypeAlertController = [UIAlertController
alertControllerWithTitle:#"selecte one:"
message:nil
preferredStyle:UIAlertControllerStyleActionSheet];
alertType1Action = [UIAlertAction
actionWithTitle:#"Type1"
style:UIAlertActionStyleDefault
handler:nil];
alertType2Action = [UIAlertAction
actionWithTitle:#"Type2"
style:UIAlertActionStyleDefault
handler:nil];
[alertTypeAlertController addAction: alertType1Action];
[alertTypeAlertController addAction: alertType2Action];
// for ipad
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
popPresenter = [alertTypeAlertController popoverPresentationController];
popPresenter.permittedArrowDirections = UIPopoverArrowDirectionLeft;
popPresenter.delegate = self;
popPresenter.sourceView = self.theTypeBtn;
popPresenter.sourceRect = CGRectMake(230, 22, 10, 10);
}
[self presentViewController:alertTypeAlertController animated:YES completion:nil];
}
Related
I am working on an app which i run on iPhone works well but when i am trying to run on iPad it crashes
Here is my code:
- (void)parseCountryStates:(NSDictionary *)json
{
countryPickerView.hidden = TRUE;
NSDictionary *listing = [json objectForKey:#"country"];
countryArray = [listing allValues];
countryIDArray = [listing allKeys];
[countryPickerView reloadAllComponents];
alertController = [UIAlertController
alertControllerWithTitle:#"Select Service Type"
message:nil
preferredStyle:UIAlertControllerStyleActionSheet];
int count = (int)[countryPickerView numberOfRowsInComponent:0];
for (int i = 0; i < count; i++)
{
UIAlertAction* button = [UIAlertAction
actionWithTitle:[[countryPickerView delegate] pickerView:countryPickerView titleForRow:i forComponent:0]
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
countryField.text = [action title];
countryStr = countryField.text;
if ([countryArray containsObject:countryStr]) {
countryidStr = [countryIDArray objectAtIndex:[countryArray indexOfObject:countryStr]];
NSLog(#"CountryidStr %#",countryidStr);
[self getState];
}
}];
[alertController addAction:button];
}
UIAlertAction* cancel = [UIAlertAction
actionWithTitle:#"Cancel"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction * action)
{
// UIAlertController will automatically dismiss the view
}];
[alertController addAction:cancel];
[self presentViewController:alertController animated:true completion:nil];
}
I am sharing the crash log of it
*** Terminating app due to uncaught exception 'NSGenericException', reason: 'Your application has presented a UIAlertController () of
style UIAlertControllerStyleActionSheet. The modalPresentationStyle of
a UIAlertController with this style is UIModalPresentationPopover. You
must provide location information for this popover through the alert
controller's popoverPresentationController. You must provide either a
sourceView and sourceRect or a barButtonItem. If this information is
not known when you present the alert controller, you may provide it in
the UIPopoverPresentationControllerDelegate method
-prepareForPopoverPresentation.
Add source view and source rect to your alertController.
[[alertController popoverPresentationController] setSourceView:self.view];
[[alertController popoverPresentationController] setSourceRect:CGRectMake(0,0,1,1)];
[[alertController popoverPresentationController] setPermittedArrowDirections:UIPopoverArrowDirectionUp];
[self presentViewController:alertController animated:true completion:nil];
actully on ipad alertcontrollers are not allowed instead you can use pop overs to diaplay kind of alert
Programtically
UIViewController *newViewCont = [[UIViewController alloc] init];
newViewCont.view = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 180, 180)];
newViewCont.modalPresentationStyle = UIModalPresentationPopover;
[self presentViewController:newViewCont animated:YES completion:nil];
UIPopoverPresentationController *pop = [newViewCont popoverPresentationController];
pop.permittedArrowDirections = UIPopoverArrowDirectionAny;
[pop setSourceView:myButton];
[pop setSourceRect:myButton.bounds];
Using storyboards
// grab the view controller we want to show
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *controller = [storyboard instantiateViewControllerWithIdentifier:#"Pop"];
// present the controller
// on iPad, this will be a Popover
// on iPhone, this will be an action sheet
controller.modalPresentationStyle = UIModalPresentationPopover;
[self presentViewController:controller animated:YES completion:nil];
// configure the Popover presentation controller
UIPopoverPresentationController *popController = [controller popoverPresentationController];
popController.permittedArrowDirections = UIPopoverArrowDirectionUp;
popController.delegate = self;
// in case we don't have a bar button as reference
popController.sourceView = self.view;
popController.sourceRect = CGRectMake(30, 50, 10, 10);
dismiss popover
[self dismissViewControllerAnimated:YES completion:nil];
There’s a new protocol called the UIPopoverPresentationControllerDelegate that is called upon dismissal and position change due to rotation or interface changes. We can even prevent a Popover from being dismissed if we wish. Here are the three methods we can implement:
- (void)popoverPresentationControllerDidDismissPopover:(UIPopoverPresentationController *)popoverPresentationController {
// called when a Popover is dismissed
}
- (BOOL)popoverPresentationControllerShouldDismissPopover:(UIPopoverPresentationController *)popoverPresentationController {
// return YES if the Popover should be dismissed
// return NO if the Popover should not be dismissed
return YES;
}
- (void)popoverPresentationController:(UIPopoverPresentationController *)popoverPresentationController willRepositionPopoverToRect:(inout CGRect *)rect inView:(inout UIView *__autoreleasing _Nonnull *)view {
// called when the Popover changes position
}
Don’t forget to conform to the protocol, and set the delegate to your reacting class.
UIPopovers are not allowed on iPads, but there is a way you can do this as other answers have indicated. Here is a Swift 5.x version.
let ac = UIAlertController(title: "Some title goes here", message: nil, preferredStyle: .actionSheet)
ac.addAction(UIAlertAction(title: "Some button name", style: .default) {
[unowned self] _ in
// stuff to do goes here
self.doSomething()
})
// iPad specific code
ac.popoverPresentationController?.sourceView = self.view
let xOrigin = nil // Replace this with one of the lines at the end
let popoverRect = CGRect(x: xOrigin, y: 0, width: 1, height: 1)
ac.popoverPresentationController?.sourceRect = popoverRect
ac.popoverPresentationController?.permittedArrowDirections = .up
present(ac, animated: true)
Replacing the the let xOrigin = nil line with one of the ones below will control where the popover appears below the navigation bar. You can also change x and y to the proper value in the bounds or frame of a different element if you have control that is below the nav bar on an iPad.
Top Left
let xOrigin = 0
Top Middle
let xOrigin = self.view.bounds.width / 2
Top Right
let xOrigin = self.view.bounds.width
Hope this helps.
Try to use the code from the first answer in the link (by Kampai):
How to use UIAlertController to replace UIActionSheet?
However, the completion handler is not even called in my code.
The alert action sheet can be dismissed after pressing both buttons but nothing inside the completion handler works.
Any idea what might be the problem? I'm new to using completion handler and have tried to find answers online, but few have the same problem as mine.
- (IBAction)takePhotoButtonPressed:(UIButton *)sender {
pressedButtonTagNumber = sender.tag;
UIAlertController *actionSheet = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
[actionSheet addAction:[UIAlertAction actionWithTitle:#"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
// Cancel button tappped
[self dismissViewControllerAnimated:YES completion:^{
}];
}]];
[actionSheet addAction:[UIAlertAction actionWithTitle:#"Take a Photo" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
NSLog(#"!");
// Take a Photo button tapped
[self dismissViewControllerAnimated:YES completion:^{
NSLog(#"0"); // NOT CALLED
// Initialize UIImagePickerController
UIImagePickerController *takePhotoImagePickerController = [[UIImagePickerController alloc] init]; takePhotoImagePickerController.delegate = self;
takePhotoImagePickerController.allowsEditing = YES;
NSLog(#"1");
// Check and assign image source
if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
NSLog(#"2");
UIAlertController *noCameraErrorSheet = [UIAlertController alertControllerWithTitle:#"Camera is not available" message:nil preferredStyle:UIAlertControllerStyleActionSheet];
[noCameraErrorSheet addAction:[UIAlertAction actionWithTitle:#"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
// Cancel button tappped
[self dismissViewControllerAnimated:YES completion:^{
}];
}]];
} else {
takePhotoImagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
// Present UIImagePickerController
[self presentViewController:takePhotoImagePickerController animated:YES completion:NULL];
}
}];
}]];
Solution:
#Paulw11 solution works great:
1) No need to dismissViewController for UIAlertController.
2) Cannot call a new UIAlertController if the one wraps it is dismissing (obviously).
3) Better to check and disable the button in advance.
UIAlertController *actionSheet = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
[actionSheet addAction:[UIAlertAction actionWithTitle:#"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
}]];
UIAlertAction *takePhotoActionButton = [UIAlertAction actionWithTitle:#"Take Photo" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
[self takePhoto];
}];
UIAlertAction *uploadPhotoActionButton = [UIAlertAction actionWithTitle:#"Upload from Library" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
[self uploadPhoto];
}];
// Disable take a photo button if source not available
if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
[takePhotoActionButton setEnabled:FALSE];
}
// Disable upload a photo button if source not available
if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) {
[uploadPhotoActionButton setEnabled:FALSE];
}
[actionSheet addAction:takePhotoActionButton];
[actionSheet addAction:uploadPhotoActionButton];
// Present action sheet.
[self presentViewController:actionSheet animated:YES completion:nil];
You don't need to call dismissViewController:animated: from within the action handler to remove the alert. UIAlertController calls this to dismiss itself prior to invoking the action handler code.
In your action handler you simply need to execute whatever should be done when that action is selected:
In this case:
In your cancel action you don't need to do anything
In your "take a photo" action you take a photo
Also, from a user experience point of view, it may be better to disable the "take a photo" or present an alert as soon as they select it rather than issuing an alert after they have attempted to take a photo; in other words indicate the problem earlier rather than later
When I am trying to present alert view controller my app is crashing.
-(void)setupAlertCtrl{
self.alertCtrl=[UIAlertController alertControllerWithTitle:#"Select Image"
message:nil
preferredStyle:UIAlertControllerStyleActionSheet];
}
- (IBAction)selectImagePressed {
**[self presentViewController:self.alertCtrl
animated:YES
completion:nil];//this funcanility is breaking**
}
Exception :
libc++abi.dylib: terminating with uncaught exception of type NSException
libc++abi.dylib: terminating with uncaught exception of type NSException
This could also happen if you've wired up a button to an IBAction that doesn't exist anymore (or has been renamed)"
If you're running into this problem than go to your storyboard, RIGHT click on the yellow box icon (view controller) at the top of the phone outline and DELETE the outlet(s) with yellow flags.
What happens in instances like this is you probably named an action, then renamed it.
Hope this will help you.
This code will definitely help you.
I suspect you are using iPad(normal action sheet crashes in iPad)
-(void)setupAlertCtrl
{
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:nil message:#"Your message" preferredStyle:UIAlertControllerStyleActionSheet];
// Remove arrow from action sheet.
[alertController.popoverPresentationController setPermittedArrowDirections:0];
//For set action sheet to middle of view.
CGRect rect = self.view.frame;
rect.origin.x = self.view.frame.size.width / 20;
rect.origin.y = self.view.frame.size.height / 20;
alertController.popoverPresentationController.sourceView = self.view;
alertController.popoverPresentationController.sourceRect = rect;
[self presentViewController:alertController animated:YES completion:nil];
}
else
{
UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:#"Your message" preferredStyle:UIAlertControllerStyleActionSheet];
[self presentViewController:alert animated:YES completion:nil];
}
}
you have to call the below function in view did load
-(void)setupAlertCtrl
Then you can open the alert on button click
You should have to write it like,
-(void)setupAlertCtrl
{
self.alertCtrl=[UIAlertController alertControllerWithTitle:#"Select Image"
message:nil
preferredStyle:UIAlertControllerStyleActionSheet];
[self presentViewController:self.alertCtrl animated:YES completion:nil];
}
-(IBAction)selectImagePressed
{
[self setupAlertCtrl];
}
Hope this will help you.
UIAlertController is a functionally identical, block-based replacement for both UIAlertView and UIActionSheet. Switching between an alert or action sheet is done by setting the preferred style when creating the controller.
UIAlertController *alertController = [UIAlertController
alertControllerWithTitle:alertTitle
message:alertMessage
preferredStyle:UIAlertControllerStyleAlert];
[self presentViewController:alertController animated:YES completion:nil];
I hope this will help you...
Its not crashing,
Just call the SetupAlertCntrl in viewDidLoad method.
Its working fine
You need to check your alertController exist or not first, if not let created it first. One more thing, UIAlertControl only can present from UIViewController so, make sure self in selectImagePressed function is kind of UIViewController.
- (IBAction)selectImagePressed {
if(self.alertController == nil) {
[self setupAlertCtrl];
}
[self presentViewController:self.alertCtrl
animated:YES
completion:nil];//this funcanility is breaking**
}
Try below code:
-(void)setupAlertCtrl
{
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:#"Choose Profile Image " message:#" " preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction* cameraAction = [UIAlertAction actionWithTitle:#"Take Photo" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
NSLog(#"Camera Action");
}];
[alertController addAction:cameraAction];
UIAlertAction* gallaryAction = [UIAlertAction actionWithTitle:#"Gallary" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
NSLog(#"Gallary Action");
}];
[alertController addAction:gallaryAction];
UIAlertAction* Cancel = [UIAlertAction actionWithTitle:#"Cancel" style:UIAlertActionStyleCancel handler:nil];
[alertController addAction:Cancel];
[self presentViewController:alertController animated:YES completion:nil];
}
// Button Click action
- (IBAction)selectImagePressed:(id)sender
{
[self setupAlertCtrl];
}
hope this will help you.
I am working on a universal app for the iPhone 6S / 6S Plus / and iPad form factors. Normally, presenting actionsheets / alertviews on an iPhone-only app is a simple manner. But my application crashes when I attempt to present these on an iPad, returning the following error:
"Terminating app due to uncaught exception 'NSGenericException', reason: 'Your application has presented a UIAlertController () of style UIAlertControllerStyleActionSheet. The modalPresentationStyle of a UIAlertController with this style is UIModalPresentationPopover. You must provide location information for this popover through the alert controller's popoverPresentationController. You must provide either a sourceView and sourceRect or a barButtonItem. If this information is not known when you present the alert controller, you may provide it in the UIPopoverPresentationControllerDelegate method -prepareForPopoverPresentation.'"
It is my understanding that I must display a popover when the application is running on an iPad instead of a conventional actionsheet. For the sake of context, the action sheet is presented by a button in a custom cell, which is in a tableview.
What is the best way to handle UIAlertControllers / Action Sheets / UIPopoverControllers in a universal app?
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
NSString *titleToUse = #"";
// switch (self.openGroup) {
// case 0:
// titleToUse = [self.deviceListData[indexPath.row] valueForKey:#"deviceName"];
// break;
//
// case 1:
// titleToUse = [self.computersData[indexPath.row] valueForKey:#"deviceName"];
// break;
//
// case 2:
// titleToUse = [self.mobileData[indexPath.row] valueForKey:#"deviceName"];
// break;
//
// case 3:
// titleToUse = [self.smartData[indexPath.row] valueForKey:#"deviceName"];
// break;
//
// default:
// break;
// }
UIAlertController *actionSheet = [UIAlertController alertControllerWithTitle:titleToUse message:nil preferredStyle:UIAlertControllerStyleActionSheet];
[actionSheet addAction:[UIAlertAction actionWithTitle:#"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
// Cancel button tappped.
}]];
[actionSheet addAction:[UIAlertAction actionWithTitle:#"Get More Info" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
AlertDetailModal *alertDetail = [[UIStoryboard storyboardWithName:#"Main" bundle:nil] instantiateViewControllerWithIdentifier:#"alertDetailModal"];
alertDetail.delegate = self;
alertDetail.securityLevel = self.securityLevel;
UINavigationController *modalNavCon = [[UINavigationController alloc] initWithRootViewController:alertDetail];
[self presentViewController:modalNavCon animated:YES completion:nil];
}]];
[actionSheet addAction:[UIAlertAction actionWithTitle:#"Bandwidth Profile" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
}]];
[actionSheet addAction:[UIAlertAction actionWithTitle:#"Alert Settings" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
}]];
[actionSheet addAction:[UIAlertAction actionWithTitle:#"Security Settings" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
}]];
[actionSheet addAction:[UIAlertAction actionWithTitle:#"Unblock Connection" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
}]];
// Present action sheet.
[self presentViewController:actionSheet animated:YES completion:nil];
}
The fact that its universal is irrelevant. You setup the alert controller's popoverPresentationController the same regardless. It will then display properly on all devices.
In this case you should set the sourceView to tableView and sourceRect to the rect for the selected row.
UIAlertController *actionSheet = [UIAlertController alertControllerWithTitle:titleToUse message:nil preferredStyle:UIAlertControllerStyleActionSheet];
actionSheet.popoverPresentationController.sourceView = tableView;
actionSheet.popoverPresentationController.sourceRect = [tableView rectForRowAtIndexPath:indexPath];
I am using Objective-C to write about some UIAlertController code.
I have more buttons, but the buttons will show different UIAlertControllers and deal with different UIAlertAction handler .
So I want to create one UIAlertController,and UIAlertAction.
Like below:
-(void) initAlert{
alertController = [UIAlertController alertControllerWithTitle:#"hint" message:#"count down alert" preferredStyle:UIAlertControllerStyleAlert];
doneAction = [UIAlertAction actionWithTitle:#"okey" style:UIAlertActionStyleDefault handler:
^(UIAlertAction *action) {
NSLog(#"show log");
}];
[alertController addAction:doneAction];
}
-(void) showAlert{
[self presentViewController:alertController animated:YES completion:nil];
}
Then I want to using different button IBAction to call the showAlert method, and set different UIAlertController title, UIAlertAction title and deal different alertAction handler.
But I encounter some problems.
I call the method in different button like below:
- (IBAction)btn1Action:(UIButton *)sender {
alertController.title = #"controller 1";
alertController.message = #"message1";
[self showAlert];
}
- (IBAction)btn2Action:(UIButton *)sender {
alertController.title = #"controller 2";
alertController.message = #"message2";
[self showAlert];
}
I don't know how to change the UIAlertAction title with the same doneAction, I search some data show the UIAlertAction is readyonly property.
So have any other methods to change UIAlertAction title? or can we delete the UIAlertController addAction: method to add other UIAlertAction?
And how can I pass different UIAlertAction handler to AlertAction for the same UIAlertController to use?
Thank you very much.
UIAlertController should not be used multiple times. Just use a new UIAlertController instance each time you want to pop up the alert.
- (IBAction)btn1Action:(UIButton *)sender {
[self showAlert:#"Controller 1" message:#"Message 1" handler:^(UIAlertAction *action) {
NSLog(#"btn1Action");
}];
}
- (IBAction)btn2Action:(UIButton *)sender {
[self showAlert:#"Controller 2" message:#"Message 2" handler:^(UIAlertAction *action) {
NSLog(#"btn2Action");
}];
}
-(void)showAlert:(NSString*)alertTitle message:(NSString*)message handler:(void (^ __nullable)(UIAlertAction *action))handler {
UIAlertController * alertController = [UIAlertController alertControllerWithTitle:alertTitle message:message preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction * doneAction = [UIAlertAction actionWithTitle:#"Ok" style:UIAlertActionStyleDefault handler:handler];
[alertController addAction:doneAction];
[self presentViewController:alertController animated:YES completion:nil];
}