Access a Navigation controller's main view programmatically - objective-c

I've got a Tab Controller with a navigation controller which has a view, as seen in the image below:
I need to retrieve the Switches Controller from within my AppDelegate so I can do some things with it at runtime.
I believe I can retrieve the NavigationController itself by doing this:
UINavigationController *navController = [tabBarController.viewControllers objectAtIndex:0];
Not really sure how to access my SwitchesController from there though. Any suggestions?

Why not make an ivar with an IBOutlet? It's probably the most flexible solution as you can now change the ordering of your viewController's without breaking your build.

Use one of the visibleViewController, topViewController properties of UINaviationController, or call:
[navigationController.viewControllers objectAtIndex:index];
Docs: http://developer.apple.com/library/ios/#documentation/uikit/reference/UINavigationController_Class/Reference/Reference.html
Hope it helps.

Related

pushViewController pushes nil

I am trying to push a view controller to the screen. The push is successful but when I later try to access any property of the pushed view controller including textboxes and labels, they are all nil.
How do I avoid this?
I am doing it this way because I need my code to decide which view controller to push. Any help is much appreciated.
myVC *vC = [self.storyboard instantiateViewControllerWithIdentifier:#"myVC"];
[self.navigationController pushViewController:vC animated:YES];
After the code you've wrote, you will need to either approach your properties like this:
vC.property = assignedValue;
Make sure you have synthesized your properties, or initialised them with a setter in the vC's viewDidLoad
If you are using Storyboard , You can actually use prepareForSegue for transferring data between ViewControllers.
And be sure your properties are declared in .h file. You can't access .m file properties.
Hope this helps.

Accessing an instance method of a ViewController From Another view controller

Let's say I have a view controller called vc1, which a synthesized property called property1, and i wants to access it from another view controller (vc2) and change it from vc2.
Now the methods created by the #syntisize to change and get properties are instance methods, so how can I get to them fro another view controller (do view controllers have instances in the app, and if so, what are they?)
Just to be clear I am using storyboards, so I never really instantiate the view controllers...
VC1.m:
-(void) yourMethod {
...
}
VC2.m
YOURViewController * vc2 = [[YOURViewController alloc]init];
[vc yourMethod];
[vc release];
Make sure to import your YOURViewController in your other view .m file
Something like that should work.
Or if you're having problems, try this tutorial here:
Tutorial on How-To Pass Data Between Two View Controllers
Hope this helps :)
While you can do it the way you describe, I think the common technique (assuming VC1 has a segue to VC2) is a bit different, where VC2 will have a property that will be set by prepareForSegue. See Configuring the Destination Controller When a Segue is Triggered in the View Controller Programming Guide.
You will need to link the storyboard views with the viewcontrollers so the view for vc1 would use the class vc1 etc for the rest (I assume you have done this because this is important when coding for different views)
Then all you need to do is where ever you are calling the properties so lets say the viewDidLoad method, declare the view controller like this:
- (void) viewDidLoad {
vc1 *viewController;
// Now you change the variable I'll presume its a UILabel so I'll change its text [viewController.property1 setText:#"I changed a different views UILabel"];
}
Let me know whether this works... Its worked for me before so should work

Push view to navigation controller from button in other class

I have a UIButton that I create in my sub class ViewController, and add it to my MainViewController.
Now, I added a target method to this button that should push another view controller to my Navigation controller (the one that in the MainViewController).
I know that the method did call when I push the button, but the view wasn't push to the Navigation Controller.
I scanned this drawing - this is the drawing (I also added part of my code):
This is the code I'm using in my button:
(remember it's in a deferent ViewController).
- (void)buttonPressed:(UIButton *)sender
{
Photo_ScreenGlobalView *photo = [[Photo_ScreenGlobalView alloc] init];
[self.navigationController pushViewController:photo animated:YES];
}
Usually I solve these situations with delegation. If there is a view controller which is subordinate to another (i.e. a "sub" view controller) but should have the ability to trigger navigation changes, etc... then it should have a weak pointer back to it's 'parent'. Then the parent VC should implement an appropriately named protocol with a callback for the child to use. The names of these things can be generic, such as #property navigationDelegate and requestNavigationToViewController: or they can be more semantic, such as #property userFormDelegate and userFormDoneButtonPressed:
Generally speaking, a subordinate view controller should not be able to directly modify navigation at it's parent's level; but it can trigger it via more loosely-coupoled interfaces like these.
i came back to let you all know how i actually did it.
after googling a lot found this nice and quick guide how to make DELEGATE
and working with delegate solved all my problems. if you need any help don't hesitate to send me PM.
this is the guide:
http://css.dzone.com/articles/do-not-publishcreating-your

Obj-C, Navigation Controller with Tab Controller am I using them incorrectly?

When I first setup my app I had some issues getting a single navigation controller to work.
I have several screens behind each tab item. I think the problem I was getting was that view controllers would show within the wrong tabs, when switching between them. I'm not bothered about keeping the last view controller used open within each tab, in fact I hide the tab bar to stop this anway now.
So at the moment I have navigation controller files for each of my tabs. I have them assigned in IB, in the mainWindow.
And I use them like this...
CategorySelTableViewController *nextController =
[[[CategorySelTableViewController alloc] initWithNibName:
#"CategorySelTableView" bundle:nil] autorelease];
nextController.hidesBottomBarWhenPushed = YES;
MyAppDelegate *delegate = (MyAppDelegate *)[[UIApplication sharedApplication]
delegate];
[delegate.billsndepsNavController pushViewController:nextController animated:YES];
However, I have some leaks.
I can't release my delegate, it causes an error.
My colleuge suggests that I should just be using self.navigationcontroller.
But this is a big change for me, I'd like to know definetively if I'm doing this wrong before I make the changes ?
When a view controller is pushed into the stack, it has two ways to access the navigation controller:
Using self.navigationController.
Accessing the navigation controller ivar in the delegate:
[UIApplication sharedApplication].delegate.navigationController
Both are equivalent but the first one is shorter, so it tends to be used more. There is no benefit from switching from one to the other. The only reason to do the extra typing is when you are not in a pushed view controller, eg: a view controller used in an independent GUI component, or an object that is not a view controller.
The delegate shouldn't be released because it exists during the whole life of the application.

How do I make a reusable XIB with it's own UIViewController?

I am trying to create a reusable "picker". It is basically like a keypad of a phone. Since I will be using this a lot in my iPhone app, I have been frustrated with trying to make it appear.
It is in its own XIB file and has its own UIViewController subclass as the FileOwner.
However, when I instantiate this with:
MonthPickerViewController *mpvc
= [[MonthPickerViewController alloc] initWithNibName:#"MonthPicker"
bundle:nil];
Nothing happens on the screen. Yet is does fire the -viewWillAppear methods, etc.
So, what am I doing wrong either in code or in InterfaceBuilder that is preventing my view to appear?
Are you pushing the view controller?
[[self navigationController] pushViewController:mpvc animated:YES];
Or are you adding the view controller's view as a subView of your current view?
First, make sure you've hooked everything up right inside Interface Builder. An easy gotcha is to forget to connect the View object up to the view outlet of your UIViewController subclass.
Then, as Adam says, you need to actually display the view. Assuming you're doing this inside the code of another view controller, you'd need something like the following if you just wanted the new view to appear ontop of your current view:
[self.view addSubview:mpvc.view];
Of if you are using a navigation controller to stack views:-
[[self navigationController] pushViewController:mpvc animated:YES];