UIAlertController does not dismiss properly on iPhone 8 device - ios

The issue is UIAlertVIewController does not work properly on iPhone 8 or iPhone 6 with iOS 12.
I need to display alert when not in a view controller and using below reference I’m able to do display alert
How to present UIAlertController when not in a view controller?
But when I tap on “OK” alert dismiss but the gray colored background does not go off, we have to kill the app only.Attached screenshot.
Same code works good in iPhone X, not sure what could be wrong in below code.
UIAlertController *alertvc = [UIAlertController alertControllerWithTitle:#"Device Registeration Error" message:"Device Error" preferredStyle:UIAlertControllerStyleAlert];
[alertvc addAction:[UIAlertAction actionWithTitle:#"Ok" style:UIAlertActionStyleCancel handler:^(UIAlertAction * action) {}]];
[[[UIApplication sharedApplication] delegate].window.rootViewController presentViewController:alertvc animated:YES completion:nil];
After tapping "OK" the grey background of the alert still exist, it does not go off, don't know where code is wrong.

Related

Why is UIAlertController not pausing code while it waits for answer?

My understanding is that normal behavior for a UIAlertController after being presented is to wait for the user to respond in other words pause other code.
In this case when the user clicks save, a UIAlertController is supposed to appear, ask the user a question about saving and then wait for the response. However, the code is continuing and the alert controller gets dismissed after about one second.
What could be wrong with the following that is preventing the code from pausing and causing the alert to disappear after about one second?
-(void) save {
if (listView.text.length>=1) {
[self fireAlertNewOrUpdate];
}
// save everything else
//dismiss view controller - this line of code may be dismissing the alert controller...
}
-(void) fireAlertNewOrUpdate {
UIAlertController *listAlert = [UIAlertController alertControllerWithTitle:#"Save list as new?" message:nil preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* yes = [UIAlertAction
actionWithTitle:#"OK"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
[self saveNewList];
}];
UIAlertAction *cancel = [UIAlertAction actionWithTitle:#"Update existing" style:UIAlertActionStyleCancel handler:^(UIAlertAction * action)
{
[self updateExisting];
}];
[listAlert addAction:cancel];
[listAlert addAction:yes];
if ([listAlert respondsToSelector:#selector(setPreferredAction:)]) {
[listAlert setPreferredAction:yes];
}
[self presentViewController:listAlert animated:YES completion:nil];
}
You've given the answer yourself, except that you've also hidden it from us. (Fortunately, you hinted at it in a comment.) It's because there's a line of code you've omitted, in save, where you dismiss the view controller. That view controller is the alert, so the alert appears in response to the call fireAlertNewOrUpdate and then immediately disappears again. In effect, you are saying present / dismiss in a single breath.
My understanding is that normal behavior for a UIAlertController after being presented is to wait for the user to respond in other words pause other code
No, not at all true. In fact, just the opposite. Your "other code" just goes right on even after the alert has appeared. There is basically nothing in iOS programming where code will spontaneously "pause". For this reason, it is quite usual after you call present to present a view controller to do nothing further in that code.

UIAlertController in wrong position

I have the situation where the alert is showing up in the upper left-hand corner of the screen (and cut off), as described in
UIAlertController is moved to buggy position at top of screen when it calls `presentViewController:`
My code is copy and paste from Apple's documentation:
- (void) alertHere
{
UIAlertController* alert = [UIAlertController
alertControllerWithTitle:#"My Alert"
message:#"This is an alert."
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {}];
[alert addAction:defaultAction];
[self presentViewController:alert animated:YES
completion:nil];
}
I am calling this from a UIViewController.
I simply don't understand the stackoverflow discussion referenced above, nor the answers. I need something a poor simple programmer from steppes can understand.
Apple doesn't consider this a bug (apparently), but I don't understand why and I certainly don't understand how to fix it.
Thank you for a nice simple solution, or at least a simple description of what I'm doing wrong.
According to this post Attempt to present UIViewController on UIViewController whose view is not in the window hierarchy It seems you call alertHere from viewDidLoad so for solved your problem you must call it in ViewDidAppear.
The answer lies here: How to present UIAlertController when not in a view controller?
It took my a while to understand it, but once implemented, it works.

How can I implement the feature in my iOS app?

First Image: This view contains 2 navigation bar with tableview. In the second navigation bar, there is one button.
Second and Third Image: When I click on the navigation button (second) one view will appear like this screenshot and according to the selected title will change on navigation.
Again I I select click on the navigation button, again view will appear and when we select an option according to that option tableview will changes.
What is that pop-up view, how to add or show tableview in that view, how to achieve this feature using Objective-C?
The "popup view' in iOS is a UIAlertController: it has two subtypes: alert and action sheet. Then you need actions(those will represent each option in the actionsheet). Add each action to the action sheet then present it. Easy as that. Each action has a block that is executed when the action is selected. No need to show a tableCiew inside the actionsheet, it should stay as close to native as possible to keep the interface familiar to users. Refer to the human interface guidelines for more information.
UIAlertController *actionSheet = [UIAlertController alertControllerWithTitle:#"Title" message:#"Your message here" preferredStyle: UIAlertControllerStyleActionSheet ];
UIAlertAction *action = [UIAlertAction actionWithTitle:#"First item" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
NSLog(#"first item pressed");
}];
[actionSheet addAction:action];
[self presentViewController:actionSheet animated:YES completion:nil];

dismiss UIAlertController presented by a modal view controller

I seem to be running into a problem similar to one in an unresolved posted question: UIAlertController dismissing his presentingViewController
I am presenting a modal view controller on top of a normal UIViewController. Then I'm popping up an alert on that modal view controller. When I push "ok" to dismiss the alert (generated with the code below), the modal view controller is also dismissed.
UIAlertAction *ok = [UIAlertAction actionWithTitle:#"OK"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action{
[self dismissViewControllerAnimated: YES completion: nil];}];
UIAlertController *alert = [UIAlertController alertControllerWithTitle:#"Sign up problem."
message:#"Some fields are empty. Please check your inputs and try again."
preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:ok];
[self presentViewController:alert animated:YES completion:nil];
How can I dismiss just the alert?
I realize I can avoid this problem by using a navigation controller type setup instead and hiding the navigation bar, so I Get the same feel as the modal view controller, but this seems silly. Thanks.
Don't call self dismissViewController in the button handler. That specifically states that you want the view controller dismissed.
You don't need to dismiss the alert. It will automatically dismiss itself. The only thing you should do in the button handler is perform whatever action you need. Do nothing if you don't need to do anything.
If your alert is simply a message and you don't need to perform any action, just do this:
UIAlertAction *ok = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault handler:nil];
You don't need to dismiss or remove the UIAlertController manually in any way in a button handler - it does that itself.
Just remove the call to dismissViewControllerAnimated:completion:.

Replace button in UIActionSheet with UIView

I want to replace one of the buttons in my UIActionSheet with a UIView. I am integrating Facebook into my app, and the log in button (FBLoginView) is a subclass of UIView. I want use this view as a button in a UIActionSheet. Is this possible?
Edit: I am trying to integrate facebook sharing in my app. For that, i hacve to use their sdk. For logging into facebook, they provide their own custom made view called 'FBLoginView' which has been made as a subclass of UIView. I just have to allocate memory and add this view to my own view. Then clicking on the view will call all functions provided in the sdk, open the fb app or safari and ask for login and password etc. and then come back to the app.
Now I want to put this button in a UIActionSheet. In the sheet I don't see an option for customizing its buttons. Even if there was an option, how can I use the UIView to create UIButton?
It's not a good idea to mess around with UIActionSheet.
From UIActionSheet Class Reference:
Subclassing Notes
UIActionSheet is not designed to be subclassed, nor should you add views to its hierarchy. If you need to present a sheet with more customization than provided by the UIActionSheet API, you can create your own and present it modally with presentViewController:animated:completion:.
There are a quite a few action sheet replacements. Look at https://www.cocoacontrols.com/search?q=uiactionsheet for a starting list.
My suggestion is to find one with the features you like instead of hacking UIActionSheet.
I found this one from another user on StackOverflow, you might find it useful, as I did
Add UIView as subView on UIActionSheet
Good luck and let us know if you find any other solutions :)
UPDATE: I'd stay away from UIACtionSheet, as it's deprecated in iOS 8 onward. You need to use UIAlertController now. I'd use something like this:
UIAlertController * alert=[UIAlertController alertControllerWithTitle:#"Connection Method"
message:#"Select Connection Method"
preferredStyle:UIAlertControllerStyleActionSheet];
//These will essentially be the buttons that we used to create for UIActionSheet. They are created pretty much the same way as how they used to,
//but you have to declare their corresponding action here too.
UIAlertAction* firstAction = [UIAlertAction actionWithTitle:#"Title1"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
declaredVariable = NO;
[alert dismissViewControllerAnimated:NO completion:nil];
[self doSomethingHereOrExecuteTheFunctionYouNeed];
}];
UIAlertAction* secondAction = [UIAlertAction actionWithTitle:#"Title2 and so on"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
BOOL newVarable = YES;
[alert dismissViewControllerAnimated:NO completion:nil];
[self followAlertControllerChoice];
}];
UIAlertAction* cancel = [UIAlertAction actionWithTitle:#"Cancel button"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction * action) {
[alert dismissViewControllerAnimated:YES completion:nil];
}];
//Add buttons ("Actions") here
[alert addAction:firstAction];
[alert addAction:secondAction];
[alert addAction:cancel];
//Finally, present your alertcontroller
[self presentViewController:alert animated:YES completion:nil];
AFAIK, you can only add textfields to the alertcontroller, and you can do it like this:
[alertController addTextFieldWithConfigurationHandler:^(UITextField *textField) {
textField.placeholder = #"Enter your text here";
textField.textAlignment = NSTextAlignmentLeft;
//So On so forth
}];
Apparently, Apple doesn't want us to subclass the UIAlertController, per here:
The UIAlertController class is intended to be used as-is and does not
support subclassing. The view hierarchy for this class is private and
must not be modified.

Resources