Selecting index of tabBarController and passing data - ios

I want to select the UIViewController at index 0 of my tabbarcontroller while passing data to it. It seems I am accessing the UINavigationController instead. Anyone know why this occurs?
SearchViewController *search = (SearchViewController *)[self.tabBarController.viewControllers objectAtIndex:0];
[search initWithText:#"This is a test"];
[[self.tabBarController.viewControllers objectAtIndex:1] pushViewController:search animated:NO];
// Also receive the error using this:
self.tabBarController.selectedViewController = search;
Error:
-[UINavigationController initWithText:]: unrecognized selector sent to instance

Wow, now I feel silly. This worked.
UINavigationController *navController = [self.tabBarController.viewControllers objectAtIndex:0];
SearchViewController *search = [navController.viewControllers objectAtIndex:0];
[search initWithText:#"This is a test"];
self.tabBarController.selectedViewController = navController;

Related

UITabbarController selectedIndex and selectedViewController do not work

I've tried to put following two lines into - (void)viewDidLoad.
self.tabBarController.selectedIndex = 3;
self.tabBarController.selectedViewController = [self.tabBarController.viewControllers objectAtIndex:3];
At that time, only Tabbar index to change 3 but View Controller remained at default view controller, mean 0. Is there any thing missing in my coding?
Solution: Try by moving your,
self.tabBarController.selectedIndex = 3;
self.tabBarController.selectedViewController = [self.tabBarController.viewControllers objectAtIndex:3];
portion of your code to UIVIewController's
- (void)viewDidAppear:(BOOL)animated
I hope it will help you
Reason: You have to let your UIViewController to load fully first before you trigger an extra action on it.
Try this definitely it works:
UINavigationController *nc = [[self.tabBarController viewControllers] objectAtIndex:0];
id vc = [[nc viewControllers] objectAtIndex:0];
if ([vc isKindOfClass:[YourViewController class]])
{
[[self appDelegate].tabBarController setSelectedIndex:3];
}

How do I use a UITabBarController using the same ViewController for every tab?

and change the content and title of the ViewController depending on which tab is selected.
Is it possible?
Below is what I tried within my UITabBarController's viewDidLoad function
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
NSMutableArray * tabs = [[NSMutableArray alloc] init];
EventsViewController * upcomingEvents = (EventsViewController *)[[self viewControllers] objectAtIndex:0];
upcomingEvents.title = #"Upcoming Events";
upcomingEvents.events = [[NSArray alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"Data" ofType:#"plist"]];
[tabs addObject:upcomingEvents];
EventsViewController * myEvents = (EventsViewController *)[[self viewControllers] objectAtIndex:1];
myEvents.title = #"My Events";
myEvents.events = [[NSArray alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"MyEvents" ofType:#"plist"]];
[tabs addObject:myEvents];
[self.tabBarController setViewControllers:tabs animated:YES];
}
This results in the error
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UINavigationController setEvents:]: unrecognized selector sent to instance 0x108fe3b50'
My current storyboard setup
EDIT:
In the end with some help and understand from Unkn0wn.Bit.
I scrapped the custom UITabBarController and just adjusted my viewWillAppear function in my EventsViewController (UITableViewController) to change the source depending on the selectedIndex of the tabBarController.
Effectively using the same view (with different information) for multiple tabBar buttons using two separate NSMutableArrays (myEvents, upcomingEvents).
(void)viewWillAppear:(BOOL)animated {
if([self.tabBarController selectedIndex]) {
self.events = self.myEvents;
self.navBar.title = #"My Events";
} else {
//temporary instead run function that either downloads events or tries to update if necessary
self.events = self.upcomingEvents;
self.navBar.title = #"Upcoming Events";
}
}
This part of the error message:
-[UINavigationController setEvents:]
tells you that you are calling setEvents: on an instance of UINavigationController and it doesn't respond.
Your issue is that you are forgetting your view controller hierarchy because you have your EventsViewController instances inside navigation controllers so you need to traverse the hierarchy to call the correct instances.
i.e.:
UINavigationController *navController = (UINavigationController *)[[self viewControllers] objectAtIndex:0];
EventsViewController *upcomingEvents = [navController topViewController];
If you use interface builder, In your story board file create multiple view controllers ( ctrl+drag from your Tab Bar Controller to assign them to tabs ) design your view as you wish, but set their custom class to one same class !
You could use multiple instances of your ViewController subclass, and that would give you what you want. But if you wanted to simply use the exact same instance for each, then you would want to use a UITabBar directly, not a UITabBarController. You could add the UITabBar to your UIViewController subclass and implement the UITabBarDelegate protocol.

Passed NSString always null

I need to pass an NSString from one view to another. I do in my first view controller:
-(IBAction)btnCreate_click:(id)sender
{
CreateMatchTableViewController *matcObj = [[CreateMatchTableViewController alloc]init];
matcObj.createBtnPressed = #"pressed";
[self.tabBarController setSelectedIndex:1];
}
CreateMatchTableViewController is my second view controller and createBtnPressed ia NSString object in second view controller.
In viewDidLoad of second view controller:
- (void)viewDidLoad
{
[super viewDidLoad];
// MatchListViewController *obj = [[MatchListViewController alloc]init];
NSString *stringFromFirstView = createBtnPressed;
NSLog(#"check===>%#",stringFromFirstView);//...always null
}
Please help!!
Seems that in your first view controller you are creating a new instance of CreateMatchTableViewController. You do not want that because you have your CreateMatchTableViewController instance already in the tab bar controller...
Try something like this:
-(IBAction)btnCreate_click:(id)sender
{
CreateMatchTableViewController *matcObj = [self.tabBarController.viewControllers objectAtIndex:1];
matcObj.createBtnPressed = #"pressed";
[self.tabBarController setSelectedIndex:1];
}
EDIT
-(IBAction)btnCreate_click:(id)sender
{
UINavigationController *navigationController = [self.tabBarController.viewControllers objectAtIndex:1];
CreateMatchTableViewController *matcObj = [[navigationController viewControllers] objectAtIndex:0];// I put 0 assuming you have a CreateMatchTableViewController as the navigation controller's root view controller
matcObj.createBtnPressed = #"pressed";
[self.tabBarController setSelectedIndex:1];
}
on CreateMatchTableViewController write a method like following:
(void)setStringFromFirstViewController:(NSString*)str{
NSString *stringFromFirstView = str;
NSLog(#"check===>%#",stringFromFirstView);
}
Now on "first view controller" do the following:
-(IBAction)btnCreate_click:(id)sender{
CreateMatchTableViewController *matcObj = [[CreateMatchTableViewController alloc]init];
[matcObj setStringFromFirstViewController: #"pressed"];
[self.tabBarController setSelectedIndex:1];
}
Try
NSString* a = [[NSString alloc] initWithString:createBtnPressed];

Inject a NSString text to another UIViewController

I'm trying to pass a NSString text to a UIViewController in button "click" event in iOS. I wrote following code.
self.detailViewController = [[DetailViewController alloc] initWithNibName:#"DetailViewController" bundle:nil];
self.detailViewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentModalViewController:self.detailViewController animated:YES];
self.detailViewController.urlAddress = #"http://www.google.com";
I've already declared urlAddress property in detailViewController.
After I tested with NSLog in viewWillAppear, it shows only null values, not the urlAddress string. How can I solve it?
You're setting the string after the view controller was already presented. Switch that and you should be good.
Note the order of methods being called:
initWithNibName
viewDidLoad
viewWillAppear
Your string is changed only after all three have done their work.
Change your code to:
self.detailViewController = [[DetailViewController alloc] initWithNibName:#"DetailViewController" bundle:nil];
self.detailViewController.urlAddress = #"http://www.google.com";
self.detailViewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentModalViewController:self.detailViewController animated:YES]; //Triggers viewWillAppear eventually

self.navigationController is null after it is assign as RootViewController?

I created a new xcode project as View-based application, and I have a set of UIViewController(s) which I plan to use inside separate UINavigationController(s).
In ParentViewController.m before all the UINavigationController(s) and after all myViewControllers been initiated:
NSMutableArray *navControllers = [[NSMutableArray array];
for (id aVC in self.myViewControllers) {
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:aVC];
//[aVC setNavigationController:navController];
[navController setNavigationBarHidden:YES];
[navController setToolbarHidden:YES];
[navControllers addObject:navController];
[navController release];
}
_navigationControllers = [[NSArray arrayWithArray:navigationControllers] retain];
_navigationControllers is retained as a member of ParentViewController, so I suppose all my navigation controllers initiated inside for-loop are kept by _navigationControllers so they won't be released or become nil, but when I try to use navigationController in MyViewController to push SomeOtherViewController, it doesn't work:
- (IBAction)pushDetailView {
[self.navigationController pushViewController:self.detailViewController animated:YES];
}
I put a breakpoint before pushViewController:someOtherViewController, and "po [self navigationController]", the console tells me it is a nil reference.
I assumed that when I do
[[UINavigationController alloc] initWithRootViewController:aVC], the underlying mechanism would assign the navigationController as aVC.navigationController, because the Apple "View Controller Programming Guide for iOS" does the same without assigning navigationController to rootController.
Unless I unmark the second line of the for-loop //[aVC setNavigationController:navController];, the navigationController does not exist in aVC.
Am I misunderstanding the mechanism? Is there another solution for my case?
Thanks in advance!
_navigationControllers = [NSMutableArray array];
for (id aVC in self.myViewControllers) {
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:aVC];
//[aVC setNavigationController:navController];
[navController setNavigationBarHidden:YES];
[navController setToolbarHidden:YES];
[navControllers addObject:navController];
}
// assuming index 0 navigation controller is with 'ParentViewController'
self.rootViewController = [_navigationControllers objectAtIndex:0];
check with this.

Resources