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
}
Related
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.
After sending SMS from my phone(it's working properly) in my project using the MFMessageComposeViewController I can't get back to the app or press cancel. Instead I'm stuck in Apple SMS interface and I can't do anything else then to restart the app. Do I miss something in didFinishWithResult or could it be something else? Thanks
- (IBAction)sendSMS:(id)sender {
MFMessageComposeViewController *controller =
[[[MFMessageComposeViewController alloc] init] autorelease];
if([MFMessageComposeViewController canSendText])
{
NSString *str= #"Hi";
controller.body = str;
controller.recipients = [NSArray arrayWithObjects:
#"", nil];
controller.delegate = self;
[self dismissViewControllerAnimated:YES
completion:nil];
[self presentViewController:controller animated:YES completion:nil];
}
}
- (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult) result
{
switch (result) {
case MessageComposeResultCancelled:
break;
case MessageComposeResultFailed:
{
UIAlertView *warningAlert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Failed to send SMS!" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[warningAlert show];
break;
}
case MessageComposeResultSent:
break;
default:
break;
}
[self dismissViewControllerAnimated:YES completion:nil];
}
Ive the following code which is working fine , but when I add UIAlertView its start giving me exc_bad_access and the app hanged ,
The main idea is to show alert when timestamp dedtected ,
any tips what im doing wrong ?
- (void) onPayload:(PayloadEvent *) event {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSString *header = #"[OnPayload] ";
if (event.payloadType == TYPE_IDENTIFIED) {
if ((event.contentID != -1) && (event.timeStamp == -1)) {
[mUI performSelectorOnMainThread: #selector(Trace:) withObject:[NSString stringWithFormat:#"%# StaticID detected: %x\t\tConfidence: %f\n", header,(int)event.contentID, event.confidence] waitUntilDone:NO];
}
if ((event.timeStamp != -1) && (event.contentID == -1)) {
[mUI performSelectorOnMainThread: #selector(Trace:) withObject:[NSString stringWithFormat:#"%# Timestamp detected: %f\t\tConfidence: %f\n", header, event.timeStamp, event.confidence] waitUntilDone:NO];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Poll" message:#"MY alert Poll" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles: nil];
[alert show];
[alert release];
}
}
else if (event.payloadType == TYPE_NOT_IDENTIFIED) {
[mUI performSelectorOnMainThread: #selector(Trace:) withObject:[NSString stringWithFormat:#"%# Content not marked\n", header] waitUntilDone:NO];
}
else if (event.payloadType == TYPE_MARKED_BUT_NOT_IDENTIFIED) {
[mUI performSelectorOnMainThread: #selector(Trace:) withObject:[NSString stringWithFormat:#"%# Content marked but not identified\n", header] waitUntilDone:NO];
}
[event release];
[pool release];
}
My error appear here
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Poll" message:#"MY alert Poll" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles: nil];
[alert show]; <<=====
[alert release];
Any code that changes the UI should be called from the main thread:
dispatch_async(dispatch_get_main_queue(), ^{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Poll" message:#"MY alert Poll" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles: nil];
[alert show];
[alert release];
});
On the contrary to some comments, the view that is displaying the alert will retain the UIAlertView instance, so there is no need to call autorelease instead of release.
Considering that you are calling -performSelectorOnMainThread a few times in the same method, I imagine it's being called on a background thread. UI changes must occur on the main thread, and thus, you should be calling [alert show]; on the main thread in order to bypass the error.
[alert performSelectorOnMainThread:#selector(show) withObject:nil waitUntilDone:NO];
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;
}
}
I have one strange problem.I have two UItextfields in my view and a button.When i click on button.I have changed the frame of view in animation block but it's resigning later here is my code if someone told me about this i'll be thankful
-(IBAction)SignINClicked
{
[Email resignFirstResponder]; //TextField
[Password resignFirstResponder];//TextField
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.10];
[[self view] setFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height)];
[UIView commitAnimations];
sleep(0.10);
if([Email.text isEqualToString:#""] || [Password.text isEqualToString:#""])
{
if([Email.text isEqualToString:#""] && [Password.text isEqualToString:#""])
{
UIAlertView *Error = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Please fill email and password" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[Error show];
[Error release];
}
else if([Email.text isEqualToString:#""])
{
UIAlertView *Error = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Please fill email" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[Error show];
[Error release];
}
else if([Password.text isEqualToString:#""])
{
UIAlertView *Error = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Please fill password" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[Error show];
[Error release];
}
}
else
{
[AppDelegate startLoading];
BOOL isCorrectUser=[self logIn:Email.text Password:Password.text];
if (isCorrectUser==TRUE)
{
if(checkboxSelected==1)
[self rememberMe:YES];
else
[self rememberMe:NO];
[self performSelector:#selector(ShowDashboard) withObject:nil afterDelay:5];
}
else
{
[AppDelegate endLoading];
UIAlertView *Error = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Either user name/password is incorrect" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[Error show];
[Error release];
}
}
}
-(void)startLoading
{
[UIApplication sharedApplication].networkActivityIndicatorVisible=YES;
if(MyWaitViewObj==nil)
{
MyWaitViewObj = [[MyWaitViewController alloc] initWithNibName:#"MyWaitView" bundle:nil];
}
[NSThread detachNewThreadSelector:#selector(showMyWaitView) toTarget:self withObject:nil];
[NSThread sleepForTimeInterval:0.1];
}
-(void)endLoading
{
[MyWaitViewObj.view removeFromSuperview];
[UIApplication sharedApplication].networkActivityIndicatorVisible=NO;
}
Now when i click on signin button the [appdelegate startloading] method executes first and then keyboard hides.While actually it should hide the keyboard first and then start loading
Try taking out the sleep statement. If you need something to happen after a delay, put it in it's own method and call it with:
[self performSelector:#selector(someMethod:) withObject:nil afterDelay:someTimeDelay];