I'm trying to display a UIAlertController with some action buttons. It works fine on the iPhone, because it pops from the bottom of the device. I have a problem with the ipad, the UIAlertController does not center properly. It shows a bit off to the right. I can subtract from the x coordinate by subtracting say 150f. Is there a way to just get it center?
UIAlertController * view= [UIAlertController
alertControllerWithTitle:#"My Title"
message:#"Select your Choice"
preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction* ok = [UIAlertAction
actionWithTitle:#"OK"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
//Do some thing here
[view dismissViewControllerAnimated:YES completion:nil];
}];
UIAlertAction* cancel = [UIAlertAction
actionWithTitle:#"Cancel"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
[view dismissViewControllerAnimated:YES completion:nil];
}];
[view addAction:ok];
[view addAction:cancel];
view.popoverPresentationController.sourceView = self.view;
view.popoverPresentationController.sourceRect = CGRectMake(self.view.bounds.size.width / 2.0, self.view.bounds.size.height / 2.0, 0.0, 0.0);
[self presentViewController: view animated:YES completion:nil];
If you have simple actions then better to use Alertstyle, it centers automatically or if you insist to use Actionsheet style, try setting popoverPresentationController.permittedArrowDirections = 0 this works nice with a fixed orientation but fails if you rotate in iPad.
// Alert
- (void) showAlert
{
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:#"TEst" message:#"test Message" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
}];
[alertController addAction:cancelAction];
[[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:alertController animated:YES completion:nil];
}
Related
in my app i have tableview and for clear all cells i given an action to clear button.
button work correctly and all cell deleted. but i want to give a option to user to canceled
i used UIAlertController class and its work only one time after i chosen delete button.(its work every time if i chosen cancel button)
warning in console:
Warning:
Attempt to present UIAlertController on HistoryViewController which is already presenting UINavigationController
- (IBAction)showNormalActionSheet:(id)event
{
UIAlertController *alertController = [UIAlertController
alertControllerWithTitle:nil
message:nil
preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction *cancelAction = [UIAlertAction
actionWithTitle:NSLocalizedString(#"Cancel", #"Cancel action")
style:UIAlertActionStyleCancel
handler:^(UIAlertAction *action)
{
NSLog(#"Cancel action");
}];
UIAlertAction *resetAction = [UIAlertAction
actionWithTitle:NSLocalizedString(#"Clear all recent", #"Reset action")
style:UIAlertActionStyleDestructive
handler:^(UIAlertAction *action)
{
[self onDeleteClick];
NSLog(#"Reset action");
}];
[alertController addAction:resetAction];
[alertController addAction:cancelAction];
[self presentViewController:alertController animated:YES completion:nil];
}
//- (IBAction)onDeleteClick:(id) event {
- (void)onDeleteClick {
linphone_core_clear_call_logs([LinphoneManager getLc]);
[tableController loadData];
editButton.hidden = ([tableView.dataSource tableView:tableView numberOfRowsInSection:0] == 0);
if(editButton.selected) {
[editButton toggle];
[self onEditClick:nil];
}
}
I'm trying to change the background highlight color for my alertcontroller. For eg in the below image, right now the default background highlight for a cell is light gray, I need to change it to some other color. I saw various post on changing the tint color but I dont need to change the title color only the background highlight. Is this possible?
//This is my current code
- (IBAction)showAlert:(UIButton *)sender {
UIAlertController *alert =[UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction* save = [UIAlertAction
actionWithTitle:#"Save"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
//Perform some action
}];
UIAlertAction* saveas = [UIAlertAction
actionWithTitle:#"Save As"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
//Perform some action
}];
UIAlertAction* discard = [UIAlertAction
actionWithTitle:#"Discard"
style:UIAlertActionStyleDestructive
handler:^(UIAlertAction * action)
{
//Perform some action
}];
[alert addAction:save];
[alert addAction:saveas];
[alert addAction:discard];
[alert setModalPresentationStyle:UIModalPresentationPopover];
UIPopoverPresentationController *popPresenter = [alert popoverPresentationController];
popPresenter.sourceView = sender;
popPresenter.sourceRect = sender.bounds;
[self presentViewController:alert animated:YES completion:nil];
}
I found one weird behavior of UIAlertController in Objective-C. I have added two actions in it but I found when user selects any action - handler call back get call after approx 1 sec. I am wondering why this delay is happening to get call back. Is it possible to avoid this by any way?
- (IBAction)openAlert:(id)sender {
UIAlertController * alert= [UIAlertController
alertControllerWithTitle:#"Info"
message:#"You are using UIAlertController"
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* okBtn = [UIAlertAction
actionWithTitle:#"OK"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
// Delay ~ 1 sec to get control here
self.view.backgroundColor = [UIColor blackColor];
}];
UIAlertAction* cancelBtn = [UIAlertAction
actionWithTitle:#"Cancel"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction * action)
{
}];
[alert addAction:okBtn];
[alert addAction:cancelBtn];
[self presentViewController:alert animated:YES completion:nil];
}
Its on main thread. To make sure I tried below code snippet.
dispatch_async(dispatch_get_main_queue(), ^{
// Alert view code
});
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 creating an action sheet with UIAlertController, I'm seeing a top bar always show. This SO post suggests setting the title to nil - this might work on iOS 8.0, but I'm seeing a top bar on iOS 9.0.
Set message to nil also:
UIAlertController *actionSheet= [UIAlertController
alertControllerWithTitle:nil
message:nil
preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction *actionSheetButton1 = [UIAlertAction
actionWithTitle:#"Button 1"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
NSLog(#"Button 1 pressed");
}];
UIAlertAction *actionSheetButton2 = [UIAlertAction
actionWithTitle:#"Button 2"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
NSLog(#"Button 2 pressed");
}];
UIAlertAction *actionSheetButton3 = [UIAlertAction
actionWithTitle:#"Close Button"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction * action)
{
NSLog(#"Close Button pressed");
}];
[actionSheet addAction:actionSheetButton1];
[actionSheet addAction:actionSheetButton2];
[actionSheet addAction:actionSheetButton3];
[self presentViewController:actionSheet animated:YES completion:nil];
Do you also set message to nil?
This should do the trick, at least it works for me iOS9 (iPhone 6):
[UIAlertController alertControllerWithTitle:nil
message:nil
preferredStyle:UIAlertControllerStyleActionSheet];