UIAlertController is too slow in iOS 9.3 - ios

UIAlertController is too slow when performing any button action in iOS 9.3. Not sure if it's iOS 9.3 problem or missing something to configure it properly.
UIAlertController *alert = [UIAlertController alertControllerWithTitle:#"My Alert"
message:#"This is an action sheet."
preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction *firstAction = [UIAlertAction actionWithTitle:#"one"
style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
NSLog(#"You pressed button one");
}];
UIAlertAction *secondAction = [UIAlertAction actionWithTitle:#"two"
style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
NSLog(#"You pressed button two");
}];
On iPhone Simulator, the action sheet button tap takes more than 10 seconds to print the log in console. Can anyone please let me know how to disable the transitions on iPhone Simulator or increase the speed.

Disable Debug/Slow Animations in simulator menu.

Related

How do I get a notification when my app is in the background iOS

I have a game app that uses bluetooth to send moves back and forth between two iOS devices. One person can send out an invitation for other players to play and then they can respond in the affirmative if they want to play.
I am currently using UIAlertController to currently display the invitation and response but it only works when the app is in the foreground. I would like to make it so when the app is in the background it is still listening for an invitation and display the invitation when one arrives, even in the background.
Here is the code I am using to get the invitation when the app is in the foreground
if ([region.identifier isEqualToString:#"com.checkers.bluetooth"]) {
[UIView animateWithDuration:1 delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{
} completion:^ (BOOL completed) {} ];
AlertView = [UIAlertController
alertControllerWithTitle:NSLocalizedString(#"PLAYGAME", nil)
message: NSLocalizedString(#"PLAYCHECKERS", nil)
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* okButton = [UIAlertAction
actionWithTitle:#"OK"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
Do things
}];
UIAlertAction* cancelButton = [UIAlertAction
actionWithTitle:#"CANCEL"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
do other things
}];
[AlertView addAction:okButton];
[AlertView addAction:cancelButton];
[self presentViewController:AlertView animated:YES completion:nil];
Can someone please help me with this. I had it working with UILocalNotifications but that has been deprecated. So I am stuck.
I would appreciate a tutorial or an example. I am using objective-c.
Thanks

In ios 8.3 and later, UIAlertView cause keyboardWillShow & keyboardWillHide called twice

While working on project, i came across this problem.
One of the controller implement thekeyboardWillShow & keyboardWillHide (Standard code from Apple Managing the Keyboard).
On Background tap,UIAlertView Appears(based on some validation), there is only one button in UIAlertView that simply close the UIAlertView.
Problem occurs here, on close of UIAlertView, keyboardWillShow & keyboardWillHide called again.
Below is the code i am having problem,
#import "ViewController.h"
#interface ViewController () <UITextFieldDelegate>
{
int timeCalledShow;
int timeCalledHide;
}
#property (weak, nonatomic) IBOutlet UITextField *textField;
#property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
- (IBAction)backgroundTapped:(id)sender;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillHide:)
name:UIKeyboardDidHideNotification
object:nil];
}
- (void)keyboardWillShow:(NSNotification *)notification {
timeCalledShow+=1;
NSLog(#"show Time Called %d", timeCalledShow);
CGSize keyboardSize = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
UIEdgeInsets contentInsets;
if (UIInterfaceOrientationIsPortrait([[UIApplication sharedApplication] statusBarOrientation])) {
contentInsets = UIEdgeInsetsMake(0.0, 0.0, (keyboardSize.height), 0.0);
} else {
contentInsets = UIEdgeInsetsMake(0.0, 0.0, (keyboardSize.width), 0.0);
}
self.scrollView.contentInset = contentInsets;
self.scrollView.scrollIndicatorInsets = contentInsets;
}
- (void)keyboardWillHide:(NSNotification *)notification {
timeCalledHide+=1;
NSLog(#"Hide Time Called %d", timeCalledShow);
self.scrollView.contentInset = UIEdgeInsetsZero;
self.scrollView.scrollIndicatorInsets = UIEdgeInsetsZero;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)backgroundTapped:(id)sender {
[[[UIAlertView alloc] initWithTitle:#"Testing" message:#"Keyboard hide & show, due to alert view" delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil] show];
[self.view endEditing:YES];
}
#end
Notes
I have already check keyboardWillShow called twice and similar questions here, but could not found answer
It works fine with iOS 7.0
Here is link of Test Code
Edit
I already know the work around codes. but the real question is, how aUIAlertView can fire akeyboardWillShow notification
Edit Code
I have tried Below code also suggested by #Chonch, but with this code keyboard never close even. Means keyboard appear again after closing Alert.
- (IBAction)backgroundTapped:(id)sender {
UIAlertController *alert = [UIAlertController alertControllerWithTitle:#"testing" message:#"Keyboard" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {}];
[alert addAction:defaultAction];
[self presentViewController:alert animated:YES completion:nil];
[self.textField resignFirstResponder];
}
Question Posted at Apple Developer Forums
UIAlertView is buggy and probably hasn't been since it was deprecated. Replace it with UIAlertController and your problem should go away
Not sure why it happens. It has probably something to do with UIAlertView trying to get the keyboard state back to what it was before. But note that there is no harm done with the additional show/hide calls. And in general, you need to be prepared for multiple show calls anyways, because they also come when the keyboard style is changed.
If you want to get rid of them, then use a UIAlertController instead, as suggested by Chonch already, and make sure the keyboard is dismissed before the Alert comes up, then it will work OK:
- (IBAction)backgroundTapped:(id)sender {
[self.textField resignFirstResponder];
alert = [UIAlertController alertControllerWithTitle:#"testing" message:#"Keyboard" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {}];
[alert addAction:defaultAction];
[self presentViewController:alert animated:YES completion:nil];
}
Note that with UIAlertController, you also need to keep a reference to the alert in the viewcontroller, otherwise it will be deallocated too soon.
I just fixed a similar issue. The keyboard keep popup after the alert dismisses
It seems like a bug of apple.
There is a simple solution:
If you are using AlertController, you can just set the animated to NO
[self presentViewController:alert animated:NO completion:nil];
Let me know if it fixed your problem

UIAlertView crashs in iOS 8.3

recently i start receiving crash reports for UIAlertView only by users that use iOS 8.3
Crashlytics reports:
Fatal Exception: UIApplicationInvalidInterfaceOrientation
Supported orientations has no common orientation with the application, and [_UIAlertShimPresentingViewController shouldAutorotate] is returning YES
The line where that crash happens is [alertView show] :
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:title
message:message
delegate:nil
cancelButtonTitle:cancelButtonTitle
otherButtonTitles:nil];
[alertView show];
that code is in the app for a long time and now it starts crashing. Did anyone experience a similar behaviour and has fixed the problem?
The main thing is :
UIApplicationInvalidInterfaceOrientation Supported orientations has no common orientation with the application
It means you have somewhere implemented
- (NSUInteger)supportedInterfaceOrientations {
return UIDeviceOrientationPortrait; // or UIInterfaceOrientationPortrait
}
UIInterfaceOrientationPortrait = UIDeviceOrientationPortrait = 0
In that function MUST be returned Mask like:
UIInterfaceOrientationMaskPortrait which is 1
try by implementing this
- (BOOL)shouldAutorotate {
return NO;
}
-(NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
check this also : Orientation issue in Lanscape mode while opening camera in iOS 7 in iPhone
Better than this you should start using UIAlertController. It has much better functionality and also for UIAlertAction you don't have to include delegate methods.
UIAlertController * alert= [UIAlertController
alertControllerWithTitle:#"Info"
message:#"You are using UIAlertController"
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* ok = [UIAlertAction
actionWithTitle:#"OK"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
[alert dismissViewControllerAnimated:YES completion:nil];
}];
UIAlertAction* cancel = [UIAlertAction
actionWithTitle:#"Cancel"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
[alert dismissViewControllerAnimated:YES completion:nil];
}];
[alert addAction:ok];
[alert addAction:cancel];
[self presentViewController:alert animated:YES completion:nil];
Important: UIAlertView is deprecated in iOS 8. (Note that UIAlertViewDelegate is also deprecated.) To create and manage alerts in iOS 8 and later, instead use UIAlertController with a preferredStyle of UIAlertControllerStyleAlert.
https://developer.apple.com/library/prerelease/ios/documentation/UIKit/Reference/UIAlertView_Class/index.html
After trying the solutions here, none of them worked for me. I'm supporting iOS 6-8 in an app, and, more than that, use some libraries that use UIAlertView internally, so simply conditionally compiling to use UIAlertController when available was not an option.
I came up with a solution that solved the problem for me. Your mileage may vary. I include the header file in the Header Prefix file so that it's sure to be included anywhere a UIAlertView is shown.
I'm posting this here for anyone who's stumbling on this problem and the solutions found around the net don't work. Hopefully it's helpful.
https://gist.github.com/joshhudnall/cdc89b61d0a545c85d1d
I created a helper for displaying UIAlertView when before iOS8 and UIAlertController after iOS8, this solves the rotation crash and also displays nicely in all versions.
https://github.com/dannyshmueli/DSAlertDisplayer

After iOS 8, can I continue to use UIActionSheet and UIAlertView?

I have apps which use UIActionSheet and UIAlertView.
In iOS8, Apple's documentation and some websites say that they are deprecated in iOS8.
UIActionSheet documentation
Important: UIActionSheet is deprecated in iOS 8. (Note that
UIActionSheetDelegate is also deprecated.) To create and manage action
sheets in iOS 8 and later, instead use UIAlertController with a
preferredStyle of UIAlertControllerStyleActionSheet.
But in Xcode 6 with deployment target 8.0 does not generate warning for the use of UIActionSheet and UIAlertView.
Normally Xcode generates warning for deprecated API.
Why doesn't Xcode generate warnings for UIActionSheet and UIAlertView?
Does this mean Apple does not actually deprecate those classes?
It is very dangerous if they actually deprecated them and Xcode does not generate warnings.
In another apple's documentation "What's New in iOS 8.0" says:
The new UIAlertController class replaces the UIActionSheet and UIAlertViewclasses as the preferred way to display alerts in your app.
https://developer.apple.com/library/ios/releasenotes/General/WhatsNewIniOS/Articles/iOS8.html
And UIActionSheet and UIAlertView is not listed on Deprecated APIs section of the documentation of the above URL.
So, this documentation means UIAlertController is preferable but UIActionSheet and UIAlertView are also still available in iOS 8.
Should I replace UIActionSheet and UIAlertView in my apps with new UIAlertController class?
Or can I continue to use UIActionSheet and UIAlertView?
It's always best to not use depreciated code, it all adds up for well written code.
So yeah, use UIAlertController.
Yes you should. Preferable leads to deprecated which leads to being cut off suddenly.
Yes, you should replace your code.
When I tried to use in my code some of the functions and delegate methods for both of the Classes UIActionSheet and UIAlertView were not working.
I was getting issues and weird results each time.
Therefore, you should not use deprecated APIs.
I am sure about this, I think if the app is uploaded to App Store with deprecated APIs then that App can be rejected.
It takes a while to figure out the new method, so you might find this code useful. I’m supporting older versions of iOS so I use a conditional to decide which to use. This code runs in my app delegate. If you are running it in a view controller, replace
[self.window.rootViewController presentViewController:alert animated:true completion:nil];
with
[self presentViewController:alert animated:YES completion:nil];
The #define is in my .pch but I put it here since it is what I use in the conditional.
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
- (void)applicationWillEnterForeground:(UIApplication *)application {
if (self.window.rootViewController) {
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(#"8.0")) {
[self displayUIAlertController];
} else {
[self displayUIAlertView];
}
}
}
- (void)displayUIAlertController {
NSString *alertMessage = [NSString stringWithFormat:#"Do you want to resume playing %# or start a new session?", GAME_NAME_TITLE];
UIAlertController *alert = [UIAlertController alertControllerWithTitle:#"Welcome Back"
message:alertMessage
preferredStyle:UIAlertControllerStyleAlert];
// You can add as many actions as you want
UIAlertAction *startNewSession = [UIAlertAction actionWithTitle:#"Start New Session"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
[self startNewSession];
}];
UIAlertAction *doNothingAction = [UIAlertAction actionWithTitle:#"Resume"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
// Do nothing
}];
// Add actions to the controller so they will appear
[alert addAction:doNothingAction];
[alert addAction:startNewSession];
// Finally present the action
[self.window.rootViewController presentViewController:alert animated:true completion:nil];
}
- (void)displayUIAlertView {
NSString *messageWithTitle = [NSString stringWithFormat:#"Do you want to resume playing %# or start a new session?", GAME_NAME_TITLE];
self.alertView = [[UIAlertView alloc] initWithTitle:#"Welcome Back"
message:messageWithTitle
delegate:self
cancelButtonTitle:#"Resume"
otherButtonTitles: #"Start New Session",nil];
[self.alertView show];
}
#pragma mark - Alert on restart
// buttonIndex 0 is cancel and the game continues
// buttonIndex 1 is Start New Session and the old results are saved and new session started
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 1) {
[self startNewSession];
}
}
Deprecated code typically means that the prior versions are not supported from the version marked and in the future. If you were building a legacy app (or an app that will be supporting prior versions) one should use the UIActionSheet and UIAlertView, however if you are updating code for iOS8+ you should use UIAlertController. The nice thing is that the code you wrote previously will not be affected so users can use a legacy version of the app without problem.
You should be able to continue using UIAlertView and UIActionSheet in iOS8 since they were deprecated in iOS8 and not in iOS7. That said, I've run into similar problems => UIAlertView automatic newline gone in iOS8?. So it appears that we may need to move to UIAlertController faster than we anticipated.

Quit iOS Application Programmatically with UIAlertView

I'm aborting my iOS Application by below methods
-(void)cancelSelected
{
UIAlertView * alert = [[UIAlertView alloc] initWithTitle:nil message:#"Are you sure you want to exit?" delegate:self cancelButtonTitle:#"No" otherButtonTitles:#"Yes", nil];
[alert show];
alert = nil;
}
Method 1 :
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex)
abort();
}
Method 2 :
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex)
[NSException raise:#"Disagree terms and conditions." format:#"Quit, Cancel"];
}
Shall I do this to quit my iOS Application programmatically?
Will this abort() method leads to reject my app?
Thanks!
See QA1561:
Q: How do I programmatically quit my iOS application?
A: There is no API provided for gracefully terminating an iOS
application.
In iOS, the user presses the Home button to close applications. Should
your application have conditions in which it cannot provide its
intended function, the recommended approach is to display an alert for
the user that indicates the nature of the problem and possible actions
the user could take — turning on WiFi, enabling Location Services,
etc. Allow the user to terminate the application at their own
discretion.
Yes the codes above will result in a reject. Use this code instead in your OK button of alert:
UIControl().sendAction(#selector(URLSessionTask.suspend), to: UIApplication.shared, for: nil)
Yes, generally you will get rejected for that.
Just present an alert to the user with a singe option, so they must approve to dismiss the alert. Then, if they dismiss (approve) they can use the app and if they don't they can't and must quit the app manually.
UIAlertController *alert = [UIAlertController alertControllerWithTitle:#"Game Over" message:#"Your time is up" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *close = [UIAlertAction actionWithTitle:#"close" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
**exit(0);**
}];
UIAlertAction *playagain = [UIAlertAction actionWithTitle:#"Play again" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
[self viewDidLoad];
}];
[alert addAction:close];
[alert addAction:playagain];
[self presentViewController:alert animated:YES completion:nil];
Use exit(0) for close current application
You can use below code to Quit iOS Application Programmatically with UIAlertView :-
Step 1:
Delegate "UIAlertViewDelegate" to your viewcontroller.h
for example:
#interface User_mail_List : UIViewController< UIAlertViewDelegate >
Step 2:
//create your UIAlertView
UIAlertView *exit_alertView= [[UIAlertView alloc] initWithTitle:#"Bizbilla !" message:#"\nAre you sure you want to Exit ?" delegate:self cancelButtonTitle:#"No" otherButtonTitles:#"Yes",nil];
[exit_alertView show];
Step 3:
-(void)alertView:(UIAlertView *)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex{
if(alertView==exit_alertView){//exit Alert Fns Start,,,,,
if(buttonIndex==1){
exit(0);
}
}//exit Alert Fns End,,,,,
}
thanks,
On your alertview button click
You can use: exit(0)?
Or,
[[NSThread mainThread] exit], using this you can quit ios app.
How about calling fatalError()
function? I've just used it, everything works as expected. (Hope this will not cause a rejection though.)

Resources