UIAlertView "non-blocking" show message does retain the view? - objective-c

I have a simple question for you... I was reading Beginning IOS 4 Development book and there is the following code example:
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:#”Hello”
message:#”This is an alert view”
delegate:self
cancelButtonTitle:#”OK”
otherButtonTitles:nil];
[alert show];
[alert release];
Then it points out that the show message shows the alert view but the code does not stop it's execution until the user dismisses the dialog, it goes on and executes the following code... since next to the show message there is a release message, does the show method retain the view until it is dismissed? Otherwise I should not release it after the show message has been sent.. I'm sorry but I did not find this information on the reference pages, so I hope this is not a (too much) stupid question.
OT: how do I activate colors on code snippets?

The window that displays the alert view retains its reference, so you don't have to.

I've wondered this and concluded that something in the show method, likely a call to addSubview: increments the retain count on the UIAlertView preventing it from being dealloc-ed.

Related

unwind or dismiss view controller not working. Xcode 6.4

I've been trying to make my pushed view controller dismiss or go back one once a confirm action has taken place. I read the many posts in stackoverflow on this subject (I've never done it before) e.g:
How to perform Unwind segue programmatically?
but had quite some problems. First of all, the ctrl drag from view controller to exit, didn't work though that seems to be a bug in Xcode 6, so I added the following workaround as advised and changed the class back and forth:
#interface RequestLessonViewController ()
- (IBAction)unwindToMyViewController: (UIStoryboardSegue *)segue;
#end
This allowed me to add in the segue from my action button to Exit. I also of course gave it an identifier (unwindSegue).
I then added the performWithSegueWithIdentifier line in my buttons code as follows:
- (IBAction)requestLessonAction:(UIButton *)sender {
// PUT CONFIRM POP UP IN HERE ???
NSLog(#"ADD A LESSON REQUEST TO LESSONS DATABASE");
UIAlertView *confRequest = [[UIAlertView alloc] initWithTitle:#"Lesson Request Submitted"
message:#"Congratulations"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[confRequest show];
[self performSegueWithIdentifier:#"unwindSegue" sender:self];
}
However my unwind is still not being kicked off.
Maybe this is still a problem due to xcode 6.4 and I need to use a different work around?
Anyway any help in this would be great
Thanks
I fixed this using this very useful and clear github from Bradley.
https://github.com/bradley/iOSUnwindSegueProgramatically
Basically I wasn't creating the following type of method on the viewcontroller I was returning too, but inside the one I was trying to exit from :-/ All clear now thanks.
- (IBAction)returnToStepOne:(UIStoryboardSegue *)segue {
NSLog(#"And now we are back.");
}

iOS strange bug with button and view change

That's the first time i post on this site.
I explain, i have to work on an already advanced project in ios.
I'm new in objective-c and it's a quite strange language when you come from java.
I have a strange issue.
In the app there is a login screen, you put mail and pass, click on a button and you go on the main view. It's work perfectly.
What i want to do is autologin. I use keychains for that, store it, retrieve it, populate my user and pass with. It's works perfectly.
If my user click on the login button it's also work perfectly.
But if i call the function myself with the code, it doesn't change the view. I can't understand why.
I put here the code where i think the change is called.
if ([result isEqualToString:#"1"]) {
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setObject:Email.text forKey:#"email"];
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Welcom back to FriendsCam!" message:#"Start sharing your video" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
//Email.text = nil;
//Password.text = nil;
UIStoryboard *MainStoryboard_iPhone=[UIStoryboard storyboardWithName:#"MainStoryboard_iPhone" bundle:nil];
self.view.window.rootViewController=[MainStoryboard_iPhone instantiateInitialViewController];
So this code is in a function who is called by the functions called when the button login is pressed if all field are correctly fill.
It work when a user manually click on the button but not when i call the button's function myself in code but the alert "welcome back" of good login show in both cases. it's only the jump in the storyboard who is broken.
Can someone explain why ? It will be very kind.
Ok i find the solution.
I was firing my method to quickly, something related with loading time of the view i think.
I delay my call with a nstimer and all work perfectly.

show alert xcode and go back after alert

i want to show the alert and when somebody click on OK they need to be send to the page before. How can i make this?
I use the following code:
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"BOOYAH!"
message:#"Saved" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
Considering you have 1 option on the alert view and the delegate is self. Use this method in the same .m file as the code above
- (void)alertView:(UIAlertView *)alertV didDismissWithButtonIndex:(NSInteger)buttonIndex
{
//go back a page
[alertV autorelease];
}
Don't forget to release the alert view. I added it in the delegate method, but you can choose to release it right after showing it (only 1 release though)
Assign the UIAlertViewDelegate to self and then implement the following method is called
- (void) alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
if (buttonIndex == buttonIndexForOK) { // Where buttonIndexForOK is the index for your ok button, in this case, that would be zero, but if you want an OK and a Cancel button this would be different.
// go back to the last page
}
}
UIAlertView follows the delegation design pattern that is extremely common in iOS development. You provide a delegate object, and when the object wants to tell you about something, it sends that delegate object a message.
In your code, you've provided self as the delegate. This means that this object needs to conform to the UIAlertViewDelegate protocol.
You will see that there are several methods you can implement to react to various events relating to the alert view. You should use the alertView:clickedButtonAtIndex: method, which provides an index parameter indicating which button was tapped.

UIAlertView with 19 buttons

I am creating a pop up dialog box (UIAlertView). It works great, except I need to choose from 19 items, and the buttons do not automatically scroll and only five fit on the screen.
So, can I make them scroll? If not, can I put a UIPickerView in an alert view? Or, is there a better way?
Code so far:
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Provider"
message:#"Please choose your provider:"
delegate:self
cancelButtonTitle:nil
otherButtonTitles:#"AT&T",#"Verizon",#"Sprint",#"Nextel",#"T-Mobile",#"Alltel",#"US Cellular",#"Virgin Mobile",#"Metro PCS",#"Boost Mobile",#"Cricket",#"Rogers(Can)",#"Telus(Can)",#"Bell Mobility(Can)",#"Fido",#"Virgin(Can)",#"O2",#"Vodaphone",#"Meteor", nil];
[alert show];
[alert release];
You might consider using a UIActionSheet instead. It will automatically scroll when you have a lot of items.
Don't create 19 buttons. Instead, use UIPickerView.
In general, use UIActionSheet or a modal view of some sort.
In this particular case, you may be able to use the CoreTelephony framework. CTCarrier has a property carrierName that is supposed to return the something similar to what you are asking for (as long as the device is connected to a cellular network).

How to release a "PopUp" view"?

I have this class that shows a popup.
I do a alloc-init on it and it comes up.
DarkVader* darkPopUp = [[DarkVader alloc] init:theButton helpMessage:[theButton.titleLabel.text intValue] isADay:NO offset:0];
It shows itself and if the user presses Ok it disappears. When do I release this?
I could do a [self release] in the class when the OK button is pressed. Is this correct?
If I do this the Analyzer says it has a retain count of +1 and gets leaked in the calling function.
If I release it just after the alloc-init the Analyzer says it has a retain count of +0 and i should not release it.
DLog(#"DarkVader retain count: %i", [darkPopUp retainCount]);
says it has a retain count of 2. I'm confused.
In short my question is: How do I release an object that gets initialized does some work and ends but no one is there to release it in the calling function.
My suggestion would be to use
[self autorelease];
when the view is closing itself. Although if you look at various standard views, then all implement callbacks to a delegate that becomes responsible for closing them; this let's the launching object be responsible for releasing the view as well. You also don't make it clear how your view (or is it a view controller) is displayed.
You could do something similar to what existing Cocoa Touch classes does. For example, see how you show an UIAlertView:
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"title" message:#"message" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
[alert release];
It's quite clear that UIAlertView does a [self retain], or more likely, gets retained when added as a subview somewhere on the screen somewhere in the show method.
There are some Cocoa Touch classes that indeed (just as Paul mentioned) do not support this way of release at once, but instead calls a delegate method and excepts the receiver to release it.
I'd say the answer is, if your DarkVader is an UIView, you should let the subview-retain take care of the retain count. If it's a UIViewController or a custom helper class, you have a few options, the delegate way being a simple and straight forward one.
If you want a custom pop-up in the style you described you should probably already be subclassing UIAlertView to begin with. Then you can use it's already implemented retain/release functionality.