I have a NavigationController based iPhone app that has a navigationBar and a toolbar. Here is basically how it works:
The applicationDelegate pushes a "SplashScreen" onto the RootViewController as a modal view. While the splash screen is up, the application does some work and based on the user's location will either just dismiss the modal view OR will dismiss the modal view and push another view onto the navigation stack.
Both the RootViewController and the child view have toolbars with an Add button. My problem is this: when the 2nd view is pushed automatically, the Add button calls the code for its PARENT controller. If you dismiss this and then press the add button again, it calls the correct code.
Here is some of my code.
in the viewDidLoad of the RootViewController I have:
addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:#selector(addClicked:)];
[self setToolbarItems:[NSArray arrayWithObjects:addButton, nil]];
in the viewDidLoad of the Child Controller (LocationListsController) I have:
addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:#selector(addClicked:)];
[self setToolbarItems:[NSArray arrayWithObjects:addButton, nil]];
(yes the same code, they both have addClicked events)
in the RootViewController, viewWillAppear is where I actually push the child view:
if (((GeoListsAppDelegate *)[[UIApplication sharedApplication] delegate]).selectedIndex != -1)
{
GeoLocation *location = [((GeoListsAppDelegate *)[[UIApplication sharedApplication] delegate]).locations objectAtIndex:((GeoListsAppDelegate *)[[UIApplication sharedApplication] delegate]).selectedIndex];
((GeoListsAppDelegate *)[[UIApplication sharedApplication] delegate]).selectedIndex = -1;
if (lController == nil)
{
LocationListsController *aController = [[LocationListsController alloc] initWithLocation:location];
self.lController = aController;
[aController release];
}
[[self navigationController] pushViewController:lController animated:YES];
}
The pushing of the view works fine. The only problem I have is the addButton on the toolbar. Does anyone have any ideas?
Try pushing the "child" view controller from viewDidAppear instead of viewWillAppear.
Related
I am having a little problem -
(BTW i have looked on
How can I present a modal view controller after selecting a contact?
but it didnt help me)
Basically i want to let the user select a contact using the - peoplePickerNavigationController. after the selection i want to presentModalViewController that will use the personRef data.
i can see that the "add person" method get called but the iphone does not present the view.
UPDATE - It works if i cancel the animation in the Dismiss dismissModalViewControllerAnimated and in the presentModalViewController, but then it looks pretty ugly.
this is the function called after the user selects the contact -
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)personRef {
TempREcordId = ABRecordGetRecordID(personRef);
BOOL hasDeleteDate = [GlobalFunctions CheckToSeeIfInHiBye:TempREcordId];
if (hasDeleteDate) {
[GlobalFunctions alert:NSLocalizedString(#"", #"") ];
}else{
[self addCustomValuesAfterSelection];
[self dismissModalViewControllerAnimated:YES];
}
return NO;
}
this is the function called but still the view is not presenting -
- (void)addPerson {
NSLog(#"#2");
AddViewController *addViewController = [[AddViewController alloc] initWithStyle:UITableViewStyleGrouped];
addViewController.delegate = self;
// Create a new managed object context for the new book -- set its persistent store coordinator to the same as that from the fetched results controller's context.
NSManagedObjectContext *addingContext = [[NSManagedObjectContext alloc] init];
self.addingManagedObjectContext = addingContext;
[addingContext release];
[addingManagedObjectContext setPersistentStoreCoordinator:[[fetchedResultsController managedObjectContext] persistentStoreCoordinator]];
addViewController.person = (Person *)[NSEntityDescription insertNewObjectForEntityForName:#"Person" inManagedObjectContext:addingContext];
addViewController.hiByeGroupId = [dataSource hibyeGroupId];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:addViewController];
[self.navigationController presentModalViewController:navController animated:YES];
[addViewController release];
[navController release];
}
thank you very much.
Just don't dismiss the people picker and present your controller modally on top of it. If you afterwards dismiss your controller at some point dismiss the people picker instead (from the caller/parent) and your ViewController will be dismissed too.
From the Apple Docs:
dismissModalViewControllerAnimated: …
If you present several modal view controllers in succession, and thus build a stack of modal view controllers, calling this method on a view controller lower in the stack dismisses its immediate child view controller and all view controllers above that child on the stack. When this happens, only the top-most view is dismissed in an animated fashion; any intermediate view controllers are simply removed from the stack.
Although by picking a person, the picker dismisses, the key is to dismiss it yourself in the delegate callback, after picking a person and than present your controller
- (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController*)peoplePicker didSelectPerson:(ABRecordRef)person {
[self.navigationController dismissViewControllerAnimated:YES completion:^{
ContactDetailViewController * vc = [[ContactDetailViewController alloc] initWithWithABRecord:person];
vc.delegate = self;
UINavigationController * nc = [[UINavigationController alloc] initWithRootViewController:vc];
[self.navigationController presentViewController:nc animated:YES completion:^{
}];
}];
}
I suppose you just have to wait until the people picker disappeared by finishing its animation which it indicates by calling viewDidDisappear. If you override and hook up in there, you should be save to present your modal controller.
I m working on one project in which I m calling other viewcontroller in the below way:--
AppDelegate *app2 = (AppDelegate *)[[UIApplication sharedApplication]delegate];
[self.navigationController pushViewController:app2.SecondForm animated:NO];
app2 =nil;
My application is navigation based and in which I have created my on back button on navigation bar
-(void)viewDidLoad
{
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Back" style:UIBarStyleBlackOpaque target:self action:#selector(Back:)];
}
in this way my Back action will call on click
-(IBAction)Back:(id)sender
{
// What code I will write over here to get the same functionality
// which is by default given by navigation controller?
}
I think you are looking for:
[self.navigationController popViewControllerAnimated:YES];
popViewControllerAnimated
I Have a view with a button. I want to press the button and that a Navigation Controller will appear, and in it there will be a back button that will bring me to the original view.
this is how i load the Navigation Controller:
-(IBAction) viewButtonPressed:(id) sender
{
[self.view addSubview:navController.view];
[self.view bringSubviewToFront:navController.view];
}
in the rootController of the NAvagtion Controller I tried this, but it does not work (the back button does not even appear):
#implementation rootViewController
- (void)viewDidLoad {
self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemEdit target:self action:#selector(customGoBack:)];
}
navigationController is the stack of viewControllers. You didn't push any controller except root to this stack, so there is no back button in the navigationBar. You can create separate controller to push it into the navigationController's stack. If you son't want to see navigationBar on your first controller's view, just send - (void)setNavigationBarHidden:YES animated:NO to your instance of UINavigationController.
Use this code,
YourViewController *yvController= [[YourViewController alloc] initWithNibName:#"YourViewController" bundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:yvController animated:NO];
Its the simplest way to navigate on different views.
I have an app, inside that an UIViewController is attached on the UIWindow.
on the view of UIViewController, i have added a button and a uiview_1 of size 100x80.
this uiview_1 contains another uiview_2 as subview of same size and this uiview_2 contains a UIImageView or a UIlable at runtime (both UIImageView and UIlable are userinteraction enabled)
now on the touch/click of UIImageView, i want to show a new view using presentModalViewController, the problem is the view is shown and using back button on the navigation bar i come to the previous/main screen.
here the problem come in picture, now i am unable to touch the button or the UIImageView.
both are not responding, but app is not crashed and nor frozen.
what is wrong in that?
Plz help in this...
----- EDIT:
Approach First:
SWVController *swvController = [[SWVController alloc] init];
UINavigationController *viewNavController = [[UINavigationController alloc] initWithRootViewController:swvController];
UIViewController *pushController = [[UIViewController alloc] init];
UIWindow *win = [[UIApplication sharedApplication] keyWindow];
[win addSubview:pushController.view];
[pushController presentModalViewController:viewNavController animated:YES];
In the swvController i have back button that calls the dismissModelViewController on click >> result is the Main screen ctrls are not responding to touch – sandy 3 hours ago
Second approach:
SWVController *swvController = [[SWVController alloc] init];
UINavigationController *viewNavController = [[UINavigationController alloc] initWithRootViewController:swvController];
UIViewController *pushController = [[UIViewController alloc] init];
[self addSubview:pushController.view];
[pushController presentModalViewController:viewNavController animated:YES];
In the swvController i have back button that calls the dismissModelViewController on click >> result is the swvController's back button on navbar is not responding – sandy 3 hours ago
3rd approach:
SWVController *swvController = [[SWVController alloc] init];
UINavigationController *viewNavController = [[UINavigationController alloc] initWithRootViewController:swvController];
SampleAppAppDelegate *appdel = [[UIApplication sharedApplication] delegate]; [appdel.viewController presentModalViewController:viewNavController animated:YES];
>> result is working fine, but the problem is i dont want to use SampleAppAppDelegate,i want to give my small Uiview (100x80) as a ctrl to other person , where my ctrl will not able to get the AppDelegate of thet app at run time. – sandy 3 hours ago
Call this method when you want to present the modal view controller:
- (IBAction)showInfo {
FlipsideViewController *controller = [[FlipsideViewController alloc] initWithNibName:#"FlipsideView" bundle:nil];
controller.delegate = self;
controller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:controller animated:YES];
[controller release];
}
Add this method to your self:
- (void)flipsideViewControllerDidFinish:(FlipsideViewController *)controller {
[self dismissModalViewControllerAnimated:YES];
}
Use a toolbar or other button and connect it to this method in your modal view controller:
- (IBAction)done {
[self.delegate flipsideViewControllerDidFinish:self];
}
All code comes from Apple.
How did you handled click/touch on UIImageView? TouchesBegan/Ended?
Try putting some logs (NSLog) and run your app in debug mode (put some breakpoints) to see if control reaches your action method...
Also, when you do presentModalViewController, you do not need to POP out with back button on navigation bar... you only need to dismissModelViewController to hide it.
As shown in the screenshot below, i have a UITableView with some info and upon selecting a row an ABUnknownPersonViewController is invoked. In order to be able to able to dismiss that and go back to the UITableView I have this code:
ABUnknownPersonViewController *unknownPersonView = [[[ABUnknownPersonViewController alloc] init] autorelease];
[unknownPersonView setUnknownPersonViewDelegate:self];
[unknownPersonView setDisplayedPerson:personRecord];
[unknownPersonView setAllowsAddingToAddressBook:YES];
UIBarButtonItem *anotherButton = [[UIBarButtonItem alloc] initWithTitle:#"Επιστροφή" style:UIBarButtonItemStylePlain
target:self action:#selector(goBackToView)];
unknownPersonView.navigationItem.title = #"Προσθήκη στις επαφές";
unknownPersonView.navigationItem.leftBarButtonItem = anotherButton;
navigationController = [[[UINavigationController alloc] initWithRootViewController:unknownPersonView] autorelease];
//navigationController = [[[UINavigationController alloc] initWithRootViewController:self] autorelease];
//self.navigationItem.rightBarButtonItem = anotherButton;
[self presentModalViewController:navigationController animated:YES];
} // didSelectRowAtIndexPath ends here
- (IBAction)goBackToView {
[self dismissModalViewControllerAnimated:YES];
}
- (void)unknownPersonViewController:(ABUnknownPersonViewController *)unknownPersonView didResolveToPerson:(ABRecordRef)person {
// CallerIDAppDelegate *delegate = (CallerIDAppDelegate *)[[UIApplication sharedApplication] delegate];
[navigationController dismissModalViewControllerAnimated:YES];
}
The problem (as you can see) is that when the ABUnknownPersonViewController is dismissed by the "Επιστροφή" button, which is "Back" actually, the view holding the tableView and the blue UIButton is moved a couple of pixels to the bottom!
Any help on what could be causing this?
Screenshot http://dl.getdropbox.com/u/1237004/problem.jpg
Debug this by checking your view's frame in -viewWillAppear, -viewDidAppear, -viewWillDisappear, and -viewDidDisappear.
Also check the view's autoresizingMask, and the parent view's autoresizesSubviews property.
I'm not sure I see the value of setting up a navigation controller here. You could just present the ABUnknownPersonViewController with [self presentModalViewController: unknownPersonView];. If you're doing it for the sake of picking up the visual navigation bar with the back button, then just add a nav bar and button to the unknown person view.
It seems like a mixed metaphor to be creating a UINavigationController but then not using its usual navigation methods (e.g., pushViewController:animated: and popViewControllerAnimated:) and instead using the modal methods inherited from UIViewController.
It seems that adding this line:
[[UIApplication sharedApplication] setStatusBarHidden:YES animated:NO];
in my viewWillAppear: made the view not to move when the modal view controller is dismissed. However now the initial position was already slightly dislocated to the bottom but fixed it by moving all the outles in IB to the top so it looks ok.