How to show time in UIAlertView? - ios

In my app I'm implementing audio recorder. Everything working fine.
But when user taps on record button I have to show UIAlertView with time in seconds.
So that user can easily understand like recording.
I don't have any idea about this.
How can I do this or suggest me any other idea please.

UIAlertView is deprecated in iOS 8, now you can use UIAlertController with a preferredStyle of alert.
If the seconds are statics you can use
UIAlertController* alert = [UIAlertController alertControllerWithTitle:#“Your title string”
message:[NSString stringWithFormat:#“Seconds: %f”,yourSecondsVariable];
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:NSLocalizedString(#"OK",nil)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {}];
[alert addAction:defaultAction];
[self presentViewController:alert animated:YES completion:nil];
I think that you can use timeIntervalSinceDate: (of NSDate) to initialize your yourSecondsVariable.

If you want the time to be dynamic (continually updating) then this should get you started.
#interface ViewController ()
#property (nonatomic, strong) UILabel *timeLabel;
#end
Implementation:
- (void)timer {
UIAlertController *alert = [UIAlertController alertControllerWithTitle:#"Time" message:#"\n\n\n" preferredStyle:UIAlertControllerStyleAlert];
self.timeLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 50, 260, 50)];
self.timeLabel.textAlignment = NSTextAlignmentCenter;
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1 repeats:YES block:^(NSTimer * _Nonnull timer) {
self.timeLabel.text = [NSDate date].description;
}];
[alert.view addSubview:self.timeLabel];
[alert addAction:[UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[timer invalidate];
}]];
[self presentViewController:alert animated:YES completion:nil];
}

Related

UIAlertViewController's alert modal cannot be dismissed by adding UIAlertAction

I almost read all related articles here but still cannot get the alert dismissed. Can anyone help? It shouldn't be that hard...
P.S. in the defaultAction callback, I tried both:
[self dismissViewControllerAnimated:YES completion:^{
NSLog(#"ok...");
}];
and
NSLog(#"ok...");
Both are out of luck
My code:
#import "ViewController.h"
#interface ViewController ()
#property (strong, nonatomic) UIAlertController *alert;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)viewDidAppear:(BOOL)animated {
UIAlertController* alert = [UIAlertController alertControllerWithTitle:#"Reminder"
message:#""
preferredStyle:UIAlertControllerStyleAlert];
self.alert = alert;
self.alert.message = #"You just logged in. The tab will be refreshed";
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
[self dismissViewControllerAnimated:YES completion:^{
NSLog(#"webview is reloading...");
}];
}];
[self.alert addAction:defaultAction];
[self presentViewController:self.alert animated:YES completion:nil];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
It will dismiss it self.If you
[self dismissViewControllerAnimated:YES completion:^{
NSLog(#"webview is reloading...");
}];
use then it will dismiss the your current View contrtoller where alert controller present after dismiss it show the Log.
- (void)viewDidAppear:(BOOL)animated
{
UIAlertController* alert = [UIAlertController alertControllerWithTitle:#"Reminder" message:#"" preferredStyle:UIAlertControllerStyleAlert];
self.alert = alert;
self.alert.message = #"You just logged in. The tab will be refreshed";
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action)
{
NSLog(#"Ok button pressed..");
NSLog(#"webview is reloading...");
}];
}];
[self.alert addAction:defaultAction];
[self presentViewController:self.alert animated:YES completion:nil];
}
Close. you just have to make a slight adjustment.
- (void)viewDidAppear:(BOOL)animated {
self.alert = [UIAlertController alertControllerWithTitle:#"Reminder"
message:#"You just logged in. The tab will be refreshed"
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleCancel handler:^(UIAlertAction * action) {
//alert dismisses itself
}];
[self.alert addAction:defaultAction];
[self presentViewController:self.alert animated:YES completion:nil];
}

Countdown NSTimer in title of a UIAlertController getting a null instead of time in seconds

I'm trying to display a countdown in the title of a UIAlertController. I want to have something like "Your session is going to expire in X seconds". My thought process was to create an NSTimer and store the time in an NSString stringWithFormat and have that string be the title of the alert controller.
Here is my countDown method:
#interface ViewController () {
NSString *seconds;
int mainInt;
NSTimer *timer;
}
- (void)countDown{
mainInt = 20;
mainInt -= 1;
seconds = [NSString stringWithFormat:#"%i", mainInt];
if (mainInt == 0) {
[timer invalidate];
}
}
and this is the UIAlertController triggered by an IBAction. When triggered the controller gets viewed modally and the title says "null seconds" wait for a few more seconds and try to trigger the logout button again and you get a title saying "19 seconds".
- (IBAction)logout:(id)sender {
timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(countDown) userInfo:nil repeats:YES];
NSString *logOutString = [NSString stringWithFormat:#"%# seconds.", seconds];
UIAlertController *alertController = [UIAlertController
alertControllerWithTitle:nil
message:logOutString
preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction *cancelAction = [UIAlertAction
actionWithTitle:NSLocalizedString(#"Cancel", #"Cancel action") style:UIAlertActionStyleCancel handler:^(UIAlertAction *action){
NSLog(#"Cancel Log out");
}];
UIAlertAction *okAction = [UIAlertAction
actionWithTitle:NSLocalizedString(#"log Out", #"Ok action") style:UIAlertActionStyleDestructive handler:^(UIAlertAction *action){
NSLog(#"Loged out");
//Log out code goes here
//When time is up, log out automatically
}];
[alertController addAction:okAction];
[alertController addAction:cancelAction];
[alertController setModalPresentationStyle:UIModalPresentationPopover];
[self presentViewController:alertController animated:YES completion:nil];
}
Your first problem is that you don't initialise seconds to anything, so it will initially be nil. This is why your alert says "null seconds". On a subsequent display of the alert, seconds will have been set by your countDown method.
Your second problem is that you aren't actually updating the message property of your alert, so you just see the value of seconds when the alert was initially displayed.
Finally, you set mainInt to 20 and then subtract 1 each time the timer fires, so it will never reach 0, it will be 20,19,20,19,20,19...
The code below initialises mainInt in the IBAction method so it isn't reset to 20 each time the tier ticks. It also updates the message property of the alert and dismisses the alert when the timer reaches 0 (it actually does it 1 second after because I think it is nicer to see 2..1...0...logout but you can change that)
#interface ViewController () {
int mainInt;
NSTimer *timer;
UIAlertController *alertController;
}
- (NSString *)countDownString {
return [NSString stringWithFormat:#"%i seconds", mainInt];
}
- (void)countDown{
mainInt -= 1;
if (mainInt < 0) {
[timer invalidate];
[alertController dismissViewControllerAnimated:YES completion:^{
// Whatever you need to do to complete the logout
}]
} else {
alertController.message=[self countDownString];
}
}
- (IBAction)logout:(id)sender {
timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(countDown) userInfo:nil repeats:YES];
mainInt=20;
alertController = [UIAlertController
alertControllerWithTitle:nil
message:[self countDownString]
preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction *cancelAction = [UIAlertAction
actionWithTitle:NSLocalizedString(#"Cancel", #"Cancel action") style:UIAlertActionStyleCancel handler:^(UIAlertAction *action){
[timer invalidate];
NSLog(#"Cancel Log out");
}];
UIAlertAction *okAction = [UIAlertAction
actionWithTitle:NSLocalizedString(#"log Out", #"Ok action") style:UIAlertActionStyleDestructive handler:^(UIAlertAction *action){
[timer invalidate];
NSLog(#"Loged out");
//Log out code goes here
//When time is up, log out automatically
}];
[alertController addAction:okAction];
[alertController addAction:cancelAction];
[alertController setModalPresentationStyle:UIModalPresentationPopover];
[self presentViewController:alertController animated:YES completion:nil];
}

Keyboard from UIAlertController dismisses with delay

I'm trying to make a login dialog in UIAlertController.
Here is my code:
+ (void)authorizationDialogShow
{
__block UITextField *loginTextField;
__block UITextField *passwordTextField;
UIAlertController *authorizationAlert = [UIAlertController alertControllerWithTitle:#"Authorization"
message:#"Enter login and password."
preferredStyle:UIAlertControllerStyleAlert];
[authorizationAlert addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
loginTextField = textField;
loginTextField.placeholder = #"Login";
}];
[authorizationAlert addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
passwordTextField = textField;
passwordTextField.placeholder = #"Password";
passwordTextField.secureTextEntry = YES;
}];
[authorizationAlert addAction:[UIAlertAction actionWithTitle:#"Login"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * _Nonnull action) {
NSString *login = loginTextField.text;
NSString *password = passwordTextField.text;
[GitAuthorization startAuthorizationWithLogin:login password:password];
}]];
[authorizationAlert addAction:[UIAlertAction actionWithTitle:#"Cancel"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction * _Nonnull action) {
NSLog(#"End editing");
[authorizationAlert.view endEditing:YES];
[loginTextField resignFirstResponder];
[passwordTextField resignFirstResponder];
}]];
[authorizationAlert show];
}
The problem is in cancel UIAlertAction. When I pressed this action, the keyboard dismissed with some delay. Not at the same time as UIAlertController. What's the problem?
I'm using pod FFGlobalAlertController. Here some example of this.
I have the same issue using UIAlertController.
My solution is to add a category on UIAlertController and call [self.view endEditing:YES] on viewWillDisappear. Import the category in prefix.pch if it's used widely.
- (void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
[self.view endEditing:YES];
}
Thank for the answer from micap. See link below for detail:
iOS 8 Keyboard Dismissed delay after modal view controller is dismissed

UIAlertController Presenting in Weird Location

Whenever I try to present this alert, it keeps appearing in some weird location.. Any ideas on how to fix this?
Screenshot
UIAlertController* alert = [UIAlertController alertControllerWithTitle:#"Logout"
message:#"Are you sure you want to logout?"
preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:#"Yes"
style:UIAlertActionStyleDestructive
handler:^(UIAlertAction * _Nonnull action) {
[[NSUserDefaults standardUserDefaults] setBool:#"NO" forKey:#"auth"];
[(AppDelegate *)[UIApplication sharedApplication].delegate changeRootViewController:[Login sharedLogin]];
}]];
[alert addAction:[UIAlertAction actionWithTitle:#"No"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction * _Nonnull action) {
[alert dismissViewControllerAnimated:YES completion:nil];
}]];
[self presentViewController:alert animated:YES completion:nil];
I think you changed window frame to double width and height so it showed there. You can log this to check.

UIAlertView first deprecated IOS 9

I have tried several ways to use UIAlertController,instead of UIAlertView. I tried several ways but I cannot make the alert action work.
Here is my code that works fine in IOS 8 and IOS 9 but is showing up with deprecated flags. I tried the elegant suggestion below but I can't make it function in this context. I need to submit my app and this is the last thing to address. Thank You for any further suggestions. I am a newbie.
#pragma mark - BUTTONS ================================
- (IBAction)showModesAction:(id)sender {
NSLog(#"iapMade: %d", iapMade3);
// IAP MADE ! ===========================================
if (!iapMade3) {
//start game here
gamePlaysCount++;
[[NSUserDefaults standardUserDefaults]setInteger:gamePlaysCount forKey:#"gamePlaysCount"];
NSLog(#"playsCount: %ld", (long)gamePlaysCount);
if (gamePlaysCount >= 4) {
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Basic"
message: THREE_PLAYS_LIMIT_MESSAGE
delegate:self
cancelButtonTitle:#"Yes, please"
otherButtonTitles:#"No, thanks", nil];
[alert show];
NSString *path = [[NSBundle mainBundle] pathForResource:#"cow" ofType:#"wav"];
_pop =[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
[_pop play];
[self dismissViewControllerAnimated:true completion:nil];
} else {
if (gamePlaysCount == 1) {
// Create & store the next 5 mins when player gets 3 more lives
nextDateToPlay = [[NSDate date] dateByAddingTimeInterval:60*60*0.1];
NSLog(#"CURRENT DATE: %#", [NSDate date]);
NSLog(#"NEXT DAY: %#", nextDateToPlay);
[[NSUserDefaults standardUserDefaults]setObject: nextDateToPlay forKey:#"nextDateToPlay"];
NSLog(#"nextDateToPlay: %#", nextDateToPlay);
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Basic"
message: THREE_PLAYS_LIMIT_MESSAGE2
delegate:self
cancelButtonTitle:#"Got it!"
otherButtonTitles:#"Start", nil];
[alert show];
} else {
if (gamePlaysCount == 3) {
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Basic"
message: THREE_PLAYS_LIMIT_MESSAGE3
delegate:self
cancelButtonTitle:#"Yep, I Know!"
otherButtonTitles:#"Start", nil];
[alert show];
}
}
}
}
}
// IAP NOT MADE =============================
#pragma mark - ALERTVIEW DELEGATE ============================
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if ([[alertView buttonTitleAtIndex:buttonIndex] isEqualToString:#"Yes, please"]) {
UIStoryboard *storyboard = self.storyboard;
MenuViewController *svc = [storyboard instantiateViewControllerWithIdentifier:#"Store"];
svc.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentViewController:svc animated:YES completion:nil];
}
}
From iOS8 Apple provide new UIAlertController class which you can use instead of UIAlertView which is now deprecated, it is also stated in deprecation message:
UIAlertView is deprecated. Use UIAlertController with a preferredStyle
of UIAlertControllerStyleAlert instead
So you should use something like this
UIAlertController * alert = [UIAlertController
alertControllerWithTitle:#"Title"
message:#"Message"
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* yesButton = [UIAlertAction
actionWithTitle:#"Yes, please"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
//Handle your yes please button action here
}];
UIAlertAction* noButton = [UIAlertAction
actionWithTitle:#"No, thanks"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
//Handle no, thanks button
}];
[alert addAction:yesButton];
[alert addAction:noButton];
[self presentViewController:alert animated:YES completion:nil];
//Calling
[self showMessage:#"There is no internet connection for this device"
withTitle:#"Error"];
//Method
-(void)showMessage:(NSString*)message withTitle:(NSString *)title
{
UIAlertController * alert= [UIAlertController
alertControllerWithTitle:title
message:message
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *okAction = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action){
//do something when click button
}];
[alert addAction:okAction];
UIViewController *vc = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
[vc presentViewController:alert animated:YES completion:nil];
}
If you want to use this alert in NSObject class you should use like:
-(void)showMessage:(NSString*)message withTitle:(NSString *)title{
dispatch_async(dispatch_get_main_queue(), ^{
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:[UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
}]];
[[[[UIApplication sharedApplication] keyWindow] rootViewController] presentViewController:alertController animated:YES completion:^{
}];
});
}
Swift version of new implementation is :
let alert = UIAlertController(title: "Oops!", message:"your message", preferredStyle: .Alert)
alert.addAction(UIAlertAction(title: "Okay.", style: .Default) { _ in })
self.presentViewController(alert, animated: true){}
Xcode 8 + Swift
Assuming self is a UIViewController:
func displayAlert() {
let alert = UIAlertController(title: "Test",
message: "I am a modal alert",
preferredStyle: .alert)
let defaultButton = UIAlertAction(title: "OK",
style: .default) {(_) in
// your defaultButton action goes here
}
alert.addAction(defaultButton)
present(alert, animated: true) {
// completion goes here
}
}
Make UIAlertController+AlertController Category as:
UIAlertController+AlertController.h
typedef void (^UIAlertCompletionBlock) (UIAlertController *alertViewController, NSInteger buttonIndex);
#interface UIAlertController (AlertController)
+ (instancetype)showAlertIn:(UIViewController *)controller
WithTitle:(NSString *)title
message:(NSString *)message
cancelButtonTitle:(NSString *)cancelButtonTitle
otherButtonTitles:(NSString *)otherButtonTitle
tapBlock:(UIAlertCompletionBlock)tapBlock;
#end
UIAlertController+AlertController.m
#implementation UIAlertController (NTAlertController)
+ (instancetype)showAlertIn:(UIViewController *)controller
WithTitle:(NSString *)title
message:(NSString *)message
cancelButtonTitle:(NSString *)cancelButtonTitle
otherButtonTitles:(NSString *)otherButtonTitle
tapBlock:(UIAlertCompletionBlock)tapBlock {
UIAlertController *alertController = [self alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
if(cancelButtonTitle != nil) {
UIAlertAction *cancelButton = [UIAlertAction
actionWithTitle:cancelButtonTitle
style:UIAlertActionStyleCancel
handler:^(UIAlertAction *action)
{
tapBlock(alertController, ALERTACTION_CANCEL); // CANCEL BUTTON CALL BACK ACTION
}];
[alertController addAction:cancelButton];
}
if(otherButtonTitle != nil) {
UIAlertAction *otherButton = [UIAlertAction
actionWithTitle:otherButtonTitle
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action)
{
tapBlock(alertController, ALERTACTION_OTHER); // OTHER BUTTON CALL BACK ACTION
}];
[alertController addAction:otherButton];
}
[controller presentViewController:alertController animated:YES completion:nil];
return alertController;
}
#end
in your ViewController.m
[UIAlertController showAlertIn:self WithTitle:#"" message:#"" cancelButtonTitle:#"Cancel" otherButtonTitles:#"Other" tapBlock:^(UIAlertController *alertController, NSInteger index){
if(index == ALERTACTION_CANCEL){
// CANCEL BUTTON ACTION
}else
if(index == ALERTACTION_OTHER){
// OTHER BUTTON ACTION
}
[alertController dismissViewControllerAnimated:YES completion:nil];
}];
NOTE: If you want to add more than two buttons then add another
more UIAlertAction to the UIAlertController.
Use UIAlertController instead of UIAlertView
-(void)showMessage:(NSString*)message withTitle:(NSString *)title
{
UIAlertController * alert= [UIAlertController
alertControllerWithTitle:title
message:message
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *okAction = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action){
//do something when click button
}];
[alert addAction:okAction];
UIViewController *vc = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
[vc presentViewController:alert animated:YES completion:nil];
}
I tried the above methods, and no one can show the alert view, only when I put the presentViewController: method in a dispatch_async sentence:
dispatch_async(dispatch_get_main_queue(), ^ {
[self presentViewController:alert animated:YES completion:nil];
});
Refer to Alternative to UIAlertView for iOS 9?.
-(void)showAlert{
UIAlertController* alert = [UIAlertController alertControllerWithTitle:#"Title"
message:#"Message"
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {}];
[alert addAction:defaultAction];
[self presentViewController:alert animated:YES completion:nil];
}
[self showAlert]; // calling Method
Check this:
UIAlertController *alertctrl =[UIAlertController alertControllerWithTitle:#"choose Image" message:nil preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction *camera =[UIAlertAction actionWithTitle:#"camera" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
[self Action]; //call Action need to perform
}];
[alertctrl addAction:camera];
-(void)Action
{
}
UIAlertController * alert = [UIAlertController
alertControllerWithTitle:#"Are you sure you want to logout?"
message:#""
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* yesButton = [UIAlertAction
actionWithTitle:#"Logout"
style:UIAlertActionStyleDestructive
handler:^(UIAlertAction * action)
{
}];
UIAlertAction* noButton = [UIAlertAction
actionWithTitle:#"Cancel"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
//Handle no, thanks button
}];
[alert addAction:noButton];
[alert addAction:yesButton];
[self presentViewController:alert animated:YES completion:nil];

Resources