Iphone Back button help - iphone

Hi guys i am trying an app this is my link http://web.missouri.edu/~dnk6y2/Shealth%20app/
1.when i click on a annotation it will go inti an another view when i click show bulding it pop back the same view with single annotation and the code iam using for this is
-(void)viewWillAppear:(BOOL)animated
{
if ((i%2==0)) {
[mapView addAnnotations:djObjects];
i++;
}
else
{
if((show1==YES))
[mapView addAnnotation:annotation];
else
[mapView addAnnotations:djObjects];
// i++;
}
}
the app is working fine when i press back button even it is showing one annotation where i need all the annpotaions to come down....
so my question is can i set an action to an back button i have gone thru the apple documentation but i have no clue...

I assume that you're using a UINavigationController. UINavigationBarDelegate is the delegate class and it implements -navigationBar:shouldPopItem. You can put the action you want to trigger in that method.
Alternately, you can put it in -viewWillDisappear after checking that the view is disappearing because it was popped from the stack:
-(void) viewWillDisappear:(BOOL)animated {
if ([self.navigationController.viewControllers indexOfObject:self]==NSNotFound) {
// action code here
}
[super viewWillDisappear:animated];
}

Related

Unbalanced calls to begin/end appearance transitions for (I believe this is UINavigationController related)

It looks like this topic comes up a lot. I read through several answers but none were the same case as mine so please excuse me if you've seen similar before.
All of my UIViewControllers are being controlled by UINavgationController. On the first UIViewController (SMOnboardingPhotoMarketingViewController), I call into my keychain wrapper class to see if there is anyone logged in (app resuming). If so I call the segue to go to my main logged in screen (SMThumbnailViewController), where I'm getting the error message: Unbalanced calls to begin/end appearance transitions for .
I have examined all of the view controller life-cycle calls to ensure that I'm calling [super method] if I over-rode them. Done.
Other than that this is just a standard push type segue for all transitions. I don't understand what is so different about this call to a segue than all the others that are triggered by button actions. Here is the code from my first view controller:
-(void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
[self loadScrollViewContent];
__weak SMOnboardingPhotoMarketingViewController *weakSelf = self;
[SMAuthentication validateStoredTokenWithCompletion:^(BOOL valid) {
if(valid){
NSLog(#"Logged in. Continue to thumbs page");
[weakSelf performSegueWithIdentifier:kSeguePhotoMarketingToThumbnails sender:self];
}
else{
[SMAuthentication logOut];
NSLog(#"invalid credentials stored. User must log in ");
}
}];
}
I've noticed that in my main view controller (the one that the above code navigates to), viewDidLoad is called, but viewDidAppear is never called. What could cause such an imbalance?
Edit: Adding info. I should state taht if I move the segue call to the outside of that block, the transition goes as normal with no error. Example:
// I know this is ugly. It is for testing only
-(void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
[self loadScrollViewContent];
__block BOOL complete = NO;
__block BOOL isValid = NO;
[SMAuthentication validateStoredTokenWithCompletion:^(BOOL valid) {
if(valid){
NSLog(#"Logged in. Continue to thumbs page");
isValid = YES;
}
else{
[SMAuthentication logOut];
NSLog(#"invalid tokens stored. User must log in ");
}
complete = YES;
}];
while (!complete) {
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}
if(isValid){
[self performSegueWithIdentifier:kSeguePhotoMarketingToThumbnails sender:self];
}
}
You probably have implemented the following ViewController custom container methods:
- (void)endAppearanceTransition
- (void)beginAppearanceTransition:(BOOL)isAppearing animated:(BOOL)animated
I once written and forgot them in a base class and they messed up the whole appearance forwarding to child controllers when using storyboards.

iPhone reuse sender after dismissed modal view

I have 15 buttons on my app, which are displayed as an image. When I click on an image the getEventContact function is called which brings up a modal view controller. In this next view a contact is selected - the modal view is dismissed and the setEventContact function is run (to return the selected contact (which is its own class)).
Is there a way to determine the previous sender which triggered the getEventContact function as it could be one of 15 buttons.
-(IBAction)getEventContact:(id)sender {
[self performSegueWithIdentifier:#"selectContact" sender:self];
}
-(void)setEventContact:(Contact *)selectedContact
{
//do something
}
Cheers.
SomeType *someVariable;
-(IBAction)getEventContact:(id)sender
{
someVariable = sender;
[self performSegueWithIdentifier:#"selectContact" sender:self];
}
-(void)setEventContact:(Contact *)selectedContact
{
//not a real method
[someVariable someMethod];
}

Login Screen with Storyboarding possible?

I am playing around with the new iOS 5 features and trying to rewriting one of my apps as pure iOS 5 app using the new storyboarding feature.
To cut a long story short, I have a start screen where the app tries to connect to a server if the user saved some login data, if not, it should ask for them.
Here is how I would do it. I create a Viewcontroller which is doing the connection thing in the viewDidLoad method. If there is no login data or the login is not successful, I need a to do a manual segue to the login screen.
Now is this even possible, or do I need 2 story boards for that ?
I have solved it by putting a login view without any segues (to or from it) like in the screenshot below:
Then, I used a custom class in the tab bar controller to show it whenever I need it.
In the tab bar controller class, I use 'viewDidLoad' to fire up the login view. To show the modal view, I do have a singleton thingy that stores some state, say BOOL isAuthenticated, where I do the magic:
- (void) performLoginIfRequired: (UIViewController *) source {
if (!self.isAuthenticated) {
NSLog(#"Is not authed");
UIStoryboard *storyboard = [UIApplication sharedApplication].delegate.window.rootViewController.storyboard;
UIViewController *loginController = [storyboard instantiateViewControllerWithIdentifier:#"loginScreen"];
[source presentModalViewController:loginController animated:YES];
} else {
NSLog(#"Is authe");
}
}
And, in my case, I wanted it to be shown when the app first starts, but also when it enters foreground again. So, I registered my tab bar controller with the notification center, so I get notified if the app is coming back:
-(void)viewDidLoad {
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(willEnterForeground:) name:UIApplicationWillEnterForegroundNotification object:nil];
}
In the willEnterForeground method, I do:
-(void) willEnterForeground: (NSNotification *)notification {
[[myStateThingy defaultState] performLoginIfRequired:self];
}
It sounds like you need to use the performSegueWithIdentifier method. Make sure both views are in the same storyboard, link them together using a Push segue, and give that segue a name. Then, from your first view controller's code simply call the performSegueWithIdentifier to perform a manual segue.
Hope this helps!
See also: Conditionally following a segue
Cheers,
Jesse L. Zamora
I had this same issue, and I solved it simply by doing the following: Instead of trying to segue to a login screen(modally or push), I made the login screen my root view controller. In the login view controller's viewWillAppear method, I check if someone's logged in already. If so, I push my home screen:
// mutableFetchResults is an array with my persistent Credentials object
if ([mutableFetchResults count] > 0) { // Someone's already logged in
[self performSegueWithIdentifier:#"Home" sender:self];
}
Also, in the Home screen view controller's viewWillAppear method, I hid the back button with this line, so the user can't go "back" to the login screen:
self.navigationItem.hidesBackButton = YES;
Finally, every page of my app has a "Sign Out" bar button on the top right. Signing out and putting the login screen up was as simple as this:
- (IBAction)signOutButtonPressed:(UIBarButtonItem *)sender {
MyAppDelegate *appDelegate = [UIApplication sharedApplication].delegate;
[appDelegate signOutCurrentUser]; // this method in my app delegate deletes the current Credentials
[self.navigationController popToRootViewControllerAnimated:YES];
}
Hope that was simple enough!
After trying many different methods, I was able to solve this problem with this:
-(void)viewWillAppear:(BOOL)animated {
// Check if user is already logged in
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
if ([[prefs objectForKey:#"log"] intValue] == 1) {
self.view.hidden = YES;
}
}
-(void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
// Check if user is already logged in
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
if ([[prefs objectForKey:#"log"] intValue] == 1) {
[self performSegueWithIdentifier:#"homeSeg3" sender:self];
}
}
-(void)viewDidUnload {
self.view.hidden = NO;
}

Unload a flipview

I need to fully UNLOAD the flipview don't ask me why but i NEED to. i have tried [super release]; and it didnt work below is my back button and then the did finish. Please help me to unload the view.
on the first view which gets activated once the flipview has finished.
- (void)flipViewControllerDidFinish:(FlipViewController *)controller
{
[self dismissModalViewControllerAnimated:YES];
}
on the flip view which is a button that hides the flip view just hides doesn't unload
- (IBAction)Back:(id)sender
{
[self.delegate flipViewControllerDidFinish:self];
}
[myFlipViewController.view removeFromSuperview];

How do i check whether my current navigationController.view = a classes.view? Reason = push notifications. + iphone

so basically in my app delegate i have a navigation.controller
This navigation controller has a view of a class named MainScreen.
In MainScreen.m , i have a IBAction which will bring me to a SelectionScreen.m page by pushing it. here is the coding for it
SelectionScreen *aSelectionScreenViewController = [[SelectionScreen alloc]initWithNibName:#"SelectionScreen" bundle:nil];
[self.navigationController pushViewController:aSelectionScreenViewController animated:YES];
[aSelectionScreenViewController release];
So how do i check if my current navigationController.view = this selectionscreen.view?
The reason for checking which current view it is, is because when i receieve a push notification, i would want to automatically switch to this SelectionScreen.m page and invoke some methods within it. But this checking can only be done in the appDelegate because the didReceiveRemoteNotification method is located in there.
This is how i'm doing it
for example if you have three ViewControllers ,and any of those have possibility to be pushed by NavigationController:
ViewControllerA
ViewControllerB
ViewControllerC
Then what you need to do is:
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
if ([[self.navigationController topViewController] isKindOfClass:[ViewControllerA class]]) {
//do sth
}
if ([[self.navigationController topViewController] isKindOfClass:[ViewControllerB class]]) {
//do sth
}
if ([[self.navigationController topViewController] isKindOfClass:[ViewControllerC class]]) {
//do sth
}
}//end of code
One way is to save selectionScreenViewController as a property of your app delegate, then:
if (self.navigationController.topViewController == self.selectionScreenViewController) {
//...
}
else {
//...
}
Hey guys, i did it in a simple way. In every view controller i had, i removed all objects and assigned an object to an array in the appdelegate. So this way, everytime i go to a new view, the value is different.
So in appdidrecieveremotenotification, i can check that array and decide on what to do accordingly.
Its just a simple way of checking.