Cocoa NSAlert does not show alert as sheet - objective-c

I have the following code which expects to show alert as sheet in AppDelegate.m.
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender {
if ([self.socket.inputStream streamStatus] == 2) {
NSStoryboard *storyBoard = [NSStoryboard storyboardWithName:#"Main" bundle:nil];
NSWindowController *mainWindowController = [storyBoard instantiateControllerWithIdentifier:#"MainWindow"];
NSAlert *alert = [[NSAlert alloc] init];
[alert addButtonWithTitle:#"OK"];
[alert setMessageText:NSLocalizedString(#"Warning", #"Warning")];
[alert setInformativeText:NSLocalizedString(#"Disconnect before quit this app!!", #"Disconnet before quit")];
[alert beginSheetModalForWindow:mainWindowController.window completionHandler:^(NSModalResponse returnCode) {
}];
return NO;
} else {
return YES;
}
}
But unfortunately, the result alert does not shown as sheet. Like the screenshot.
I can't understand why. And would like to know how can I show alert as sheet. Please help me!!

It worked for me. I don't know much about.
May be it is because of the part beginSheetModalForWindow:
In your question, it seems that beginSheetModalForWindow:mainWindowController.window
I changed it from mainWindowController.window to self.view.window and it worked, as it is given below:
[alert beginSheetModalForWindow:self.view.window completionHandler:^(NSModalResponse returnCode)
{
....
}];
May be it will help i think.

Related

How conditionally change to a new storyboard

i'm writing a little IOS app using Xcode 7 IOS 9 (objective-c). Right now I'm trying to switch from the main storyboard to the second storyboard by pressing a button called "confirm". How can i write code in ViewController.m to conditionally go to the second storyboard? So if all input is correct, user presses confirm it will go to the new storyboard, else stay and display warning message. Thank you!
UIStoryboard *storyBoard;
if (yourcondition)
storyBoard = [UIStoryboard storyboardWithName:#"StoryBoard1" bundle:[NSBundle mainBundle]];
else
storyBoard = [UIStoryboard storyboardWithName:#"StoryBoard2" bundle:[NSBundle mainBundle]];
YourTargetViewController *targetCon = [stryBoard instantiateViewControllerWithIdentifier:#"TargetControllerID"];
[self.navigationController pushViewController:targetCon animated:YES];
Hope it helps..
Try this code. May be help you.
//button Actions
- (IBAction)loginbtnClicked:(id)sender
{
[self.tfEmail resignFirstResponder];
[self.tfPasswrd resignFirstResponder];
if ([self.tfEmail.text isEqualToString:#""] || [self.tfPasswrd.text isEqualToString:#""])
{
UIAlertView *alert=[[UIAlertView alloc]initWithTitle:#“Title” message:#"You are required to fill out all fields." delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
return;
}
if ([self isEmailValid:self.tfEmail.text])
{
//put your required code here.
//Navigate to next view controller.
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main” bundle:nil];
HomeVC *homeVC =[storyboard instantiateViewControllerWithIdentifier:#"HomeVCID"];
[self.navigationController pushViewController:chatVC animated:TRUE];
}
else
{
UIAlertView *alert=[[UIAlertView alloc]initWithTitle:#“Title” message:#"Please enter valid email address." delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
}
}

NSAlert beginSheetModalForWindow does not display alert

I have the following code in a ViewController in my OS X app:
NSAlert *alert = [NSAlert new];
alert.messageText = #"Connection error";
alert.informativeText = #"You do not appear to be connected to the internet";
[alert addButtonWithTitle:#"Third button"];
[alert addButtonWithTitle:#"Second button"];
[alert addButtonWithTitle:#"Ok"];
[alert beginSheetModalForWindow:[[self view] window] completionHandler:^(NSInteger result) {
NSLog(#"Success");
}];
// [alert runModal];
When this code executes nothing happens. If I comment out the beginSheetModalForWindow line, and uncomment [alert runModal], then the alert is displayed as expected.
What am I doing wrong here that it doesn't display as a sheet?
I imagine you are trying to show the NSAlert too early (while the window is setting up) try adding a perfromselector with a delay to see if this is the case
[self performSelector:#selector(delayed) withObject:nil afterDelay:1.0];
-(void)delayed {
NSAlert *alert = [NSAlert new];
alert.messageText = #"Connection error";
alert.informativeText = #"You do not appear to be connected to the internet";
[alert addButtonWithTitle:#"Third button"];
[alert addButtonWithTitle:#"Second button"];
[alert addButtonWithTitle:#"Ok"];
[alert beginSheetModalForWindow:[self.view window] completionHandler:^(NSInteger result) {
NSLog(#"Success");
}];
}
If so, try showing it once the window has loaded, for example in
- (void)windowDidLoad {
//code here
}

Objective-C confirmation before closing a window

I want to seek confirmation with the user that he wants to close the only window and with that the whole app
So far I have this:
- (BOOL)windowWillClose:(id)sender{
NSAlert *alert = [[NSAlert alloc] init];
[alert addButtonWithTitle:#"Yes"];
[alert addButtonWithTitle:#"No"];
[alert setMessageText:#"Are you sure you want to quit?"];
[alert setInformativeText:#"Quiting will stop the machine, please make sure it is back to its origin."];
[alert setAlertStyle:NSWarningAlertStyle];
[alert setShowsSuppressionButton:YES];
NSInteger result = [alert runModal];
if ( result == NSAlertFirstButtonReturn ) {
return YES;
} else {
return NO;
}
}
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender {
return YES;
}
The window and application close before there is a allert, if I remove applicationShouldTerminateAfterLastWindowClosed my window closes, nothing happens. but when I switched it up and put the allert in applicationShouldTerminateAfterLastWindowClosed the allert worked but by than my window is already closed.
I also tried it with windowShouldClose but that didn't work either.
Any ideas on what I am doing wrong here?
Add a delegate that implements the
- (BOOL)windowShouldClose:(id)sender;
delegate method, see here: https://developer.apple.com/library/mac/documentation/Cocoa/Reference/NSWindowDelegate_Protocol/Reference/Reference.html

Two UIAlertView consecutively in didFinishLaunchingWithOptions

I want two alert views to show up only when the user opens my application for the first time -- the second to appear after the first is dismissed. I have it set up to only show the UIAlertViews when it has not been shown before and I do not need help with this. I need help figuring out how to display two alert views in a row when this is the case.
-(void) alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex does not work for me.
Here is the code I have -- remember this is in didFinishLaunchingWithOptions:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
BOOL didFirstLaunch = [defaults boolForKey:#"DidFirstLaunch"];
if (!didFirstLaunch) {
[defaults setBool:YES forKey:#"DidFirstLaunch"];
UIAlertView *successAlert = //not important
[successAlert show];
[successAlert release];
//Somehow show second alert after the first is dismissed
}
I'm gonna post a very simple solution using GCD & blocks (GCD part is just in case the alert view is created on another thread then the main thread, callback should be safe to perform on the main thread). Remember, I just coded this in like 5 mins, so you definitely should work on improving the code. One thing that's a bit ugly is the delegate parameter that is overridden in my subclass. The interface of the subclass could be changed a bit to make it more obvious of what happens ...
Anyway, here goes ...
First create a subclass of UIAlertView, make it look somewhat like the following ...
#interface FSAlertView () <UIAlertViewDelegate>
#property (nonatomic, copy) void (^dismissHandler)(NSInteger buttonIndex);
#end
#implementation FSAlertView
#synthesize dismissHandler = _dismissHandler;
- (void)showWithDismissHandler:(void (^)(NSInteger buttonIndex))dismissHandler
{
self.dismissHandler = dismissHandler;
self.delegate = self;
[self show];
}
// Alert view delegate
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
dispatch_async(dispatch_get_main_queue(), ^ {
if (_dismissHandler)
{
_dismissHandler(buttonIndex);
}
});
}
Now in the app we can create alert views like the following ...
FSAlertView *alert1 = [[FSAlertView alloc] initWithTitle:#"Alert 1"
message:#"Some message"
delegate:nil
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"Show 2nd Alert", nil];
[alert1 showWithDismissHandler:^ (NSInteger buttonIndex) {
NSLog(#"button pressed: %d", buttonIndex);
if (buttonIndex == 1)
{
UIAlertView *alert2 = [[UIAlertView alloc] initWithTitle:#"Alert 2"
message:#"Hi!"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert2 show];
}
}];
If i understand your question correctly , then this may help:
UIAlertView *firstAlert = [[UIAlertView alloc] initWithTitle:#"Alert 1" message:nil delegate:self cancelButtonTitle:nil otherButtonTitles:nil, nil];
[firstAlert show];
[self performSelector:#selector(test:) withObject:firstAlert afterDelay:2];
[firstAlert release];
UIAlertView *secondAlert = [[UIAlertView alloc] initWithTitle:#"Alert 2" message:nil delegate:self cancelButtonTitle:nil otherButtonTitles:nil, nil];
[secondAlert show];
[self performSelector:#selector(test:) withObject:secondAlert afterDelay:2];
[secondAlert release];
-(void)test:(UIAlertView*)alert{
[alert dismissWithClickedButtonIndex:-1 animated:YES];
}
This will show two alert views one after the other.
NOTE: I am not sure if you are dismissing the alerts with cancel button so i am dismissing them automatically after few seconds.
Try this:
UIAlertView *firstAlert = [[UIAlertView alloc] initWithTitle:#"Title" message:#"Message" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Ok", nil];
[firstAlert setTag:444];
[firstAlert show];
firstAlert = nil;
AlertView Delegate Method:
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
switch (alertView.tag) {
case 444:
{
//Cancel ButtonIndex = 0
if (buttonIndex == 1) {
UIAlertView *secondAlert = [[UIAlertView alloc] initWithTitle:#"Title 2" message:#"Message2" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Dismiss", nil];
[secondAlert setTag:555];
[secondAlert show];
secondAlert = nil;
}
}
break;
case 555:
{
if (buttonIndex == 1) {
NSLog(#"Code Here");
}
}
break;
}
}

Photo Library view stays on screen after choosing an image with UIImagePickerController

After I choose a picture through the UIImagePickerController interface from the Photo Library, the Photo Library view stays displayed, even though I've called dismissModelViewControllerAnimated in imagePickerController:didFinishPickingImage:editingInfo.
Has anyone seen this? These are the three relevant methods I'm using:
- (IBAction)choosePictureFromLibrary:(id)sender {
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) {
UIImagePickerController* picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.allowsImageEditing = YES;
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self presentModalViewController:picker animated:YES];
[picker release];
}
else {
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:#"Error accessing Photo Library" message:#"This device does not support a Photo Library." delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
[alert release];
}
}
- (void)imagePickerController:(UIImagePickerController*)picker didFinishPickingImage:(UIImage*)image editingInfo:(NSDictionary*)editingInfo {
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:#"Picture picked!" message:#"You picked a picture!" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
[alert release];
[picker dismissModalViewControllerAnimated:YES];
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController*)picker {
[picker dismissModalViewControllerAnimated:YES];
}
I would have thought that calling imagePickerController:didFinishPickingImage:editingInfo would completely dismiss the Photo Library view, but it doesn't seem to. Is there anything else I have to do to make it go away?
You need to access the viewController of the picker not the picker itself. Try this line instead.
[[picker parentViewController] dismissModalViewControllerAnimated:YES];
You can just call
[self dismissModalViewControllerAnimated:YES];
to dismiss any modal view controller on top of the current view.
This makes sense since you present the view controller by calling:
[self presentModalViewController:picker animated:YES];
Just an update to the answers to this
[self dismissModalViewControllerAnimated:YES];
has been deprecated in iOS 6.0 so you now need to use.
[self dismissViewControllerAnimated:YES completion:nil];
Not a huge change but for anyone that looks at this question and they are using iOS 6.0 they will need an updated answer.
[self presentModalViewController:filePicker animated:YES];
has also been deprecated in favor of
[self presentViewController:filePicker animated:YES completion:nil];