How to close an alert after some time and repeat it every 10 min - macos

In my MAC OSX application. I am throwing a an alert pop up asking user to select yes or no. if user doesnt click any of the choices and may drag it to some corner. So i wanted to autoclose it after some time and again show the same alert. so i can ensure him to take same action.
Alert code i am using is
-(bool)VpnStatusUnableToConnect:(NSString *)alertMessage
{
if (nil != alertMessage) {
NSImage *alertIcon = [NSImage imageNamed:#"dock-alert"]; //my custom image placed in support files
NSAlert *alert = [[NSAlert alloc]init];
[alert addButtonWithTitle:#"Try Again"];
[alert addButtonWithTitle:#"Cancel"];
[alert setMessageText:alertMessage];
[alert setAlertStyle:NSWarningAlertStyle];
[alert setIcon:alertIcon];
[[alert window] setTitle:#"VPN Connection Status"];
[[alert window] setBackgroundColor: NSColor.whiteColor];
if ( [alert runModal] == NSAlertFirstButtonReturn)
{
return 1;
}
else
return 0;
}
return 0;
}

Modify your code as below and give a try
-(void)yourAlert{
NSAlert *alert = [[NSAlert alloc] init];
[alert addButtonWithTitle: #"OK"];
[alert setMessageText: #"Attention!!! This a critical Alert."];
[alert setAlertStyle: NSInformationalAlertStyle];
NSTimer *myTimer = [NSTimer timerWithTimeInterval:3
target:self
selector: #selector(killWindow:)
userInfo:nil
repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:myTimer forMode:NSModalPanelRunLoopMode];
int choice = 0;
choice = [alert runModal];
if(choice != 0)
[myTimer invalidate];
}
-(void) killWindow:(NSAlert *)alert with:(NSTimer *) theTimer;
{
NSLog(#"killWindow");
[[alert window] abortModal];
}

Related

Dialog like Xcode in OS X

I want to show the dialog with text input as sheet below.
I try with NSAlert but i don't want to show app icon in dialog.
NSAlert *alert = [[NSAlert alloc] init];
[alert setMessageText:kAppTitle];
[alert setInformativeText:kMsgSetDeviceName];
[alert addButtonWithTitle:kButtonOK];
[alert addButtonWithTitle:kButtonCancel];
NSString *deviceName = #"";
NSTextField *input = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 300, 24)];
[input setStringValue:deviceName];
[alert setAccessoryView:input];
[alert beginSheetModalForWindow:self.view.window completionHandler:^(NSInteger button) {
}];
You can use http://www.knowstack.com/nsalert-cocoa-objective-c/ link to create custom alert sheet in OSX.
-(void)showCustomSheet
{
{
if (!_customSheet)
//Check the myCustomSheet instance variable to make sure the custom sheet does not already exist.
[NSBundle loadNibNamed: #"CustomSheet" owner: self];
[NSApp beginSheet: self.customSheet
modalForWindow: self.window
modalDelegate: self
didEndSelector: #selector(didEndSheet:returnCode:contextInfo:)
contextInfo: nil];
// Sheet is up here.
}
}
- (IBAction)closeMyCustomSheet: (id)sender
{
[NSApp endSheet:_customSheet];
}
- (void)didEndSheet:(NSWindow *)sheet returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo
{
NSLog(#"%s",__func__);
NSLog(#"return Code %d",returnCode);
[sheet orderOut:self];
}
The below method is required to have a different point to show the alert from
- (NSRect)window:(NSWindow *)window willPositionSheet:(NSWindow *)sheet
usingRect:(NSRect)rect
{
NSLog(#"%s",__func__);
if (sheet == self.customSheet)
{
NSLog(#"if block");
NSRect fieldRect = [self.showAlertButton frame];
fieldRect.size.height = 0;
return fieldRect;
}
else
{
NSLog(#"else block");
return rect;
}
}

UIAlertController Warning Message

I am using the below code for UIAlertController in my project.
if([[[UIDevice currentDevice] systemVersion]floatValue] >= 8.0){
UIAlertController * alert= [UIAlertController
alertControllerWithTitle:#"Input Error"
message:#"Please enter a valid email."
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* okAction = [UIAlertAction
actionWithTitle:#"OK"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
[alert dismissViewControllerAnimated:YES completion:nil];
}];
[alert addAction:okAction];
[self presentViewController:alert animated:YES completion:nil];
}
else
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Input Error"
message:#"Please enter a valid email"
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil, nil];
[alertView show];
}
I am getting the below waring message:
Warning: Attempt to present <UIAlertController: 0x7f8da58df1f0> on <MBComplaintsViewController: 0x7f8da36454d0> which is already presenting (null)
Kindly guide me how to properly use UIAlertController using Objective C.
Thanks,
Abin Koshy Cheriyan
Yes as per #Alexander you should not be dismissing the alert controller like this explicitly.
As per an apple engineer a new window gets added each time an UIAlertController is displayed so when we go for dismissing it the window is still there though the alert controller disappears.
So there are two ways to handle this -
Way 1 - No explicit dismiss
Do not explicitly dismiss the UIAlertController, let it be done by the user
Way 2 - Use your own window
Simply create a category on UIAertController
Here is the sample code -
.h
#import <UIKit/UIKit.h>
#interface UIAlertController (MyAdditions)
#property(nonatomic,strong) UIWindow *alertWindow;
-(void)show;
#end
In .m
#import "UIAlertController+MyAdditions.h"
#import <objc/runtime.h>
#implementation UIAlertController (MyAdditions)
#dynamic alertWindow;
- (void)setAlertWindow:(UIWindow *)alertWindow {
objc_setAssociatedObject(self, #selector(alertWindow), alertWindow, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (UIWindow *)alertWindow {
return objc_getAssociatedObject(self, #selector(alertWindow));
}
- (void)show {
self.alertWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.alertWindow.rootViewController = [[UIViewController alloc] init];
// window level = topmost + 1
UIWindow *topWindow = [UIApplication sharedApplication].windows.lastObject;
self.alertWindow.windowLevel = topWindow.windowLevel + 1;
[self.alertWindow makeKeyAndVisible];
[self.alertWindow.rootViewController presentViewController:self animated:YES completion:nil];
}
-(void)hide {
self.alertWindow.hidden = YES;
self.alertWindow = nil;
}
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
// just to ensure the window gets desroyed
self.alertWindow.hidden = YES;
self.alertWindow = nil;
}
To show the alert controller
UIAlertCntroller *alert = ## initialisation##;
// will show the alert
[alert show];
//to dismiss
[alert hide];
[alert dismissViewControllerAnimated:YES completion:nil];
Even you can checkout one of my sample implementation here
I don't know about your problem, but you shouldn't do that
handler:^(UIAlertAction * action)
{
[alert dismissViewControllerAnimated:YES completion:nil];
}];
It will be anyway dismissed on any of your actions.

Game Center? Xcode

I have been working ver hard on Game center. I have tested so many codes I've lost count.
I would love to know how to automatically submit score as well
here are some codes i have used but i am not sure if this will help
-(IBAction)showleaderboard:(id)sender{
GKLeaderboardViewController *leaderboardController = [[GKLeaderboardViewController alloc]init];
if (leaderboardController !=NULL) {
leaderboardController.category = self.currentLeaderboard;
leaderboardController.timeScope = GKLeaderboardTimeScopeAllTime;
leaderboardController.leaderboardDelegate = self;
[self presentModalViewController:leaderboardController animated:YES];
}
}
-(void)leaderboardViewControllerDidFinish:(GKLeaderboardViewController *)viewController{
[self dismissModalViewControllerAnimated:YES];
[viewController release];
}
-(IBAction)showAchivementLeaderboard:(id)sender{
GKAchievementViewController *achivements = [[GKAchievementViewController alloc]init];
if (achivements !=NULL) {
achivements.achievementDelegate = self;
[self presentModalViewController:achivements animated:YES];
}
}
-(void)achievementViewControllerDidFinish:(GKAchievementViewController *)viewController{
[self dismissModalViewControllerAnimated:YES];
[viewController release];
}
self.currentLeaderboard= kEasyLeaderboardID;
if ([gameCenterManager isGameCenterAvailible]) {
self.gameCenterManager= [[[GameCenterManager alloc] init] autorelease];
[self.gameCenterManager setDelegate:self];
[self.gameCenterManager authenticateLocalUser];
}else{
UIAlertView *openURLAlert = [[ UIAlertView alloc] initWithTitle:#"Game Center turned off" message:#"You are not connected to game center." delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[openURLAlert show];
[openURLAlert release];
}
To report a score you need to use GKScore as follows;
GKScore *scoreReporter = [[GKScore alloc] initWithCategory:self.gameCategory.leaderboardString];
scoreReporter.value = score;
[scoreReporter reportScoreWithCompletionHandler:^(NSError *error) {
if (error != nil) {
[[KYTGlobals instance] storeScore:score forCategory:self.gameCategory.leaderboardString];
}
}];
The above code allocates and inits a GKScore object using the identifier that you have already set up on game center for the category that you want to report a score for. You update the value for the score and then use reportScoreWithCompletionHandler making sure to test for error so that you can archive the score and report it later.

Multiple UIAlertView; each with their own buttons and actions

Im creating a view in Xcode 4.3 and im unsure how to specify multiple UIAlertView's that have their own buttons with separate actions. Currently, my alerts have their own buttons, but the same actions. Below is my code.
-(IBAction)altdev {
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:#"titleGoesHere"
message:#"messageGoesHere"
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"Continue", nil];
[alert show];
}
-(IBAction)donate {
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:#"titleGoesHere"
message:#"messageGoesHere"
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"Continue", nil];
[alert show];
}
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 1) {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"http://www.examplesite1.com"]];
}
}
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 1) {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"examplesite2.com"]];
}
}
Thanks for any help!
There is a useful property tag for UIView(which UIAlertView subclass from). You can set different tag for each alert view.
UPDATE:
#define TAG_DEV 1
#define TAG_DONATE 2
- (IBAction)altdev {
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:#"titleGoesHere"
message:#"messageGoesHere"
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"Continue", nil];
alert.tag = TAG_DEV;
[alert show];
}
- (IBAction)donate {
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:#"titleGoesHere"
message:#"messageGoesHere"
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"Continue", nil];
alert.tag = TAG_DONATE;
[alert show];
}
-(void)alertView:(UIAlertView *)alertView
clickedButtonAtIndex:(NSInteger)buttonIndex {
if (alertView.tag == TAG_DEV) { // handle the altdev
...
} else if (alertView.tag == TAG_DONATE){ // handle the donate
}
}
easier & newer
UIAlertView *alert = [[UIAlertView alloc] init...
alert.tag = 1;
UIAlertView *alert = [[UIAlertView alloc] init...
alert.tag = 2;
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if(alertView.tag == 1) {
// first alert...
} else {
// sec alert...
}
}
all done!
If you find it dificult to use delegate methods to differently identifying alert view Then you can also use This Category class to use completion Block for each AlertView.
Alert_ActionSheetWithBlocks
For eg.
UIAlertView* alert1 = [[UIAlertView alloc] initWithTitle:#"AlertView+Block 1" message:#"WithBlocks" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"OK", nil];
[alert1 showWithFinishBlock:^(UIAlertView *alertView, NSInteger buttonIndex){ //--AlertView1 Stuff here }];
UIAlertView* alert2 = [[UIAlertView alloc] initWithTitle:#"AlertView+Block 2" message:#"WithBlocks" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"OK", nil];
[alert2 showWithFinishBlock:^(UIAlertView *alertView, NSInteger buttonIndex){ //--AlertView2 Stuff here }];
I hope this one is the more easiest way as compare to tag + delegate method..
He's right but you need to add this:
-(void)alertView:(UIAlertView *)alertView
clickedButtonAtIndex:(NSInteger)buttonIndex {
if (alertView.tag == TAG_DEV && buttonIndex == 1) { // handle the altdev
...
} else if (alertView.tag == TAG_DONATE && buttonIndex == 1){ // handle the donate
}
}
if buttonIndex==1 then you're using the FIRST otherbutton. 0 would be for cancel. But just do nothing for 0
Or you could do this (check the title name), is just another option... Mind identically titled alerts though!
-(IBAction)altdev {
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:#"titleOneGoesHere"
message:#"messageGoesHere"
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"Continue", nil];
[alert show];
}
-(IBAction)donate {
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:#"titleTwoGoesHere"
message:#"messageGoesHere"
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"Continue", nil];
[alert show];
}
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 1)
{
if([[alertView title] isEqualToString:#"titleOneGoesHere"])
{
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"http://www.examplesite1.com"]];
}
else
{
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"examplesite2.com"]];
}
}

ok button for alert in mac app does not work

On a button click, I am using the below code
testViewController *myWindowController = [[testViewController alloc] initWithWindowNibName:#"RecordingsViewController"];
[myWindowController setDelegate:self];
activeModalWindow = [myWindowController window];
[NSApp beginSheet:[myWindowController window]
modalForWindow:[self window]
modalDelegate:self
didEndSelector:#selector(sheetDidEnd:returnCode:contextInfo:)
contextInfo:nil];
[NSApp runModalForWindow:[myWindowController window]];
[[myWindowController window] orderOut: self];
From this testViewController, I am showing an alert using the code
NSString *theAlertMessage = [NSString stringWithFormat: #"Already added"];
NSRunAlertPanel(#"", theAlertMessage, #"OK", nil, nil);
But on clicking ok button of this alert. My alert remains on screen. Please help!
Use this to as :
NSAlert *alert = [[NSAlert alloc] init];
[alert setAlertStyle:2];
[alert setMessageText:#"Already added"];
[alert beginSheetModalForWindow:[(AppDelegate *)[[NSApplication sharedApplication] delegate] window]
modalDelegate:self
didEndSelector:#selector(sheetDidEnd:returnCode:contextInfo:)
contextInfo:nil];
}
- (void)sheetDidEnd:(NSAlert *)alert
returnCode:(int)returnCode contextInfo:(void *)contextInfo
{
NSLog(#"clicked %d button\n", returnCode);
}
Hope it helps you.
Found an alternative, it works perfectly
NSString *theAlertMessage = [NSString stringWithFormat: #"Already added."];
NSAlert *alert = [[[NSAlert alloc] init] autorelease];
[alert setAlertStyle:NSCriticalAlertStyle];
[alert addButtonWithTitle:#"OK"];
[alert setMessageText:theAlertMessage];

Resources