Setting the Managed Object Context on a StoryBoard TabBar - Table view Controller with embedded Navigation Controller - ios

I'm trying to use CoreData with Storyboard on a TabBar - NavigationController - TableViewController configuration.
When trying to assign the Managed Object Context to the TableViewController I get
[UITabBarController topViewController]: unrecognized selector sent to instance
If I understand correctly, the problem is that I'm not getting the TableViewController instance. I've tried many things but I don't seem to be getting anywhere.
Your help is much appreciated.

I was able to fixit using Matthijs Hollemans tutorial on raywenderlich.com.
UITabBarController *tabBarController = (UITabBarController *)self.window.rootViewController;
UINavigationController *navigationController = [[tabBarController viewControllers] objectAtIndex:0];
MyViewController *controller = [[navigationController viewControllers] objectAtIndex:0];
controller.managedObjectContext = self.managedObjectContext;

Related

Error in passing managedobjectcontext from Tab bar controller to TableviewController using navigationController?

I have a tab bar controller that is connected to a navigationController.
The navigationController is connected to 3 TableviewControllers and the problem I am having is that the managedobject is not passed correctly ; I have it as Nil , the error message is :
Terminating app due to uncaught exception
'NSInvalidArgumentException', reason: '+entityForName: nil is not a
legal NSManagedObjectContext parameter searching for entity name
'MyEntityName'
Before I added navigationController I had the tab bar controller connected directly to my three TableviewControllers and the managedObject gets passed correctly, any idea what I am doing wrong ?
This is my didFinishLaunchingWithOptions code in AppDelegate :
UITabBarController *tabBarController = (UITabBarController *)self.window.rootViewController;
for (id viewController in [tabBarController viewControllers]) {
if ([viewController respondsToSelector:#selector(setManagedObjectContext:)]) {
[viewController setManagedObjectContext:self.managedObjectContext];
}
}
PS: If you need additional peaces of code to understand my issue I'll be glad to post it.
I fixed it by changing my code in didFinishLaunchingWithOptions ; my new code is :
UITabBarController *tabBarController = (UITabBarController *)self.window.rootViewController;
NSArray *allTabs = tabBarController.viewControllers;
// Navigation Controller in the tab of BreakFasts
UINavigationController *navigationController = [allTabs objectAtIndex:0];
MyTableViewController *controller1 = (MyTableViewController *)navigationController.topViewController;
controller1.managedObjectContext = self.managedObjectContext;

Accessing a Storyboard ViewController from AppDelegate issue

I am trying to access an Array variable in a view controller in an application that is using storyboards.
BACKGROUND:
I have been following along with the Ray Wenderlich tutorial on Storyboards.
Once I finished the tutorial, I went back tried a different route, though I’m having trouble accessing a view controller. Everything is pretty much the same except my set up is the initial Scene is a View Controller. I am to the part where the author is adding some data to NSMutableArray in his table.
THEIR CODE THAT I AM USING AS A GUIDE
UITabBarController *tabBarController = (UITabBarController *)self.window.rootViewController;
UINavigationController *navigationController = [tabBarController viewControllers][0];
PlayersViewController *playersViewController = [navigationController viewControllers][0];
playersViewController.players = _players;
I was hoping it would be a simple as replicating what I had seen with view controllers, passing along the appropriate type, but no.
I have View Controller > View Controller > Navigation View Controller > UITableViewController.
MY CODE:
UIViewController *vc = (UIViewController*)self.window.rootViewController;
UIViewController vc1 = [vc viewController][0];
UINavigationController *nc = [vc1 viewController][0];
SearchViewTableViewController *svc = [nc viewControllers][0];
svc.myarray = _myarray;
I have tried multiple combinations and am getting nowhere.
There has got to be a simpler way for me to reference classes/view/scenes.
Any help?
Make sure you are importing the ViewController header file.
Make sure you have given you ViewController a Storyboard identifier.
Then something like this should work:
MyViewController *myVC = [[UIStoryboard storyboardWithName:#"Main" bundle:nil] instantiateViewControllerWithIdentifier:#"MyViewController"];
myVC.myMutableArray = [NSMutableArray new];
....

Receiving NSException when trying to change UITabBar icon

I have a UINavigationController that displays a UITabBarController. I am trying to add custom icons for the tab bars. I have placed the following code in AppDelegate.m didFinishLaunchingWithOptions:
UITabBarController *tabBarController = (UITabBarController *)self.window.rootViewController;
UITabBar *tabBar = tabBarController.tabBar;
UITabBarItem *tabBarItem1 = [tabBar.items objectAtIndex:0];
tabBarItem1.selectedImage = [[UIImage imageNamed:#"iconSelected"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal ];
tabBarItem1.image = [[UIImage imageNamed:#"icon"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal ];
tabBarItem1.title = nil;
With this code I receive the following NSException:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UINavigationController tabBar]: unrecognized selector sent to instance 0x7faed26343e0'
My assumption is that somehow in *tabBar I need to access the tabBar through the UINavigationController. (I.E. - UITabBar *tabBar = UINavigationController.tabBarController.tabBar;) However, this does not work either.
What is the proper way to achieve what I am looking to do?
If your tabBarController is within a navigation controller, you need to get a reference to it from that navigation controller. It can be found as the first object in the navigation controllers' viewControllers property (or, if no other controllers have been pushed onto the navigation controller, the topViewController property). Replace:
UITabBarController *tabBarController = (UITabBarController *)self.window.rootViewController;
with:
UINavigationController *navCtrl = (UINavigationController *)self.window.rootViewController;
UITabBarController *tabBarController = (UITabBarController *)navCtrl.viewControllers[0];

add a tabbed view as a main view to a navigation-based iphone app

I am relatively new to iOS, hence I apologize for any inconsistency in my question. I need help with the following issue with an app I'm trying to build. My issue is this: The app i am working has a navigation based functionality with a tableview(daily filled by user) and a detailed tableview listing the inputs of the user, but this is just one functionality of the app.
I want to have a main tab based view where one of the tabs(each tab representing a functionality) points to this module.
I wanted to ask for steps and changes i need to make to for example app delegate or rootviewcontroller(I can post the code if it helps better) to make is so that the app starts with a mutli-tabbed bar view where one tab refers to view linked to the rootviewontroller of the navigation-based app.
For summary: Need a main tab bar view where one tab points to the rootviewcontroller highlighted in the screenshot(link below)
If helpful here is a relevant function code i have in app delegate :
- (void)applicationDidFinishLaunching:(UIApplication *)application
{
UINavigationController *navigationController = (UINavigationController *)self.window.rootViewController;
RootViewController *rootViewController = (RootViewController *)[[navigationController viewControllers] objectAtIndex:0];
rootViewController.managedObjectContext = self.managedObjectContext;
//Next TWO LINES FOR COLOR BACKGROUND
[[UINavigationBar appearance] setBackgroundImage:[[UIImage alloc] init] forBarMetrics:UIBarMetricsDefault];
[[UINavigationBar appearance] setBackgroundColor:[UIColor redColor]];
}
PS:Here is the screenshot for the storyboard: where i would like to have one tab refer to the view(highlighted in the screenshot) which is linked class rootviewcontroller.m/h
The screenshot: http://i.stack.imgur.com/G9AXI.png
edit: The actual question can be seen as: How and what do i need to do to have a tabbarviewcontroller which i would add with storyboard become my rootviewcontroller instead of the navigationcontroller(highlighted in black in the screenshot: http://i.stack.imgur.com/G9AXI.png).
My current rootviewcontroller.m manages anything related to the tableview of the current navigationviewcontroller, do i need to change that also?.
I apologize for excessiv details, I am really new to iOS dev.
From this one http://i.stack.imgur.com/suLBm.png I tried to embedd in tab barviewcontrol only with storyboard to this one http://i.stack.imgur.com/TZxLo.png I tried to embedd in a tab controller just by story but i get an error :'NSInvalidArgumentException', reason: '-[UIViewController setManagedObjectContext:]: unrecognized selector sent to instance 0x8184e30'
classes related to this are(especially rootviewcontroller.m which is a navigationcontroller for now:
AppDelegate.{h,m}
Configures the Core Data stack and the first view controllers.
- (void)applicationDidFinishLaunching:(UIApplication *)application
{
UINavigationController *navigationController = (UINavigationController *)self.window.rootViewController;
RootViewController *rootViewController = (RootViewController *)[[navigationController viewControllers] objectAtIndex:0];
rootViewController.managedObjectContext = self.managedObjectContext;
}
RootViewController.{h,m}
Manages a table view for listing all values entered. Provides controls for adding and removing these values.
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationItem.leftBarButtonItem = self.editButtonItem;
}
DetailViewController.{h,m}
Manages a detail display for display details of each entered value.
My initial guess is that i need to change the rootviewcontroller appdidfinishlaunching.
Any suggestions ?
In fact now you have:
- (void)applicationDidFinishLaunching:(UIApplication *)application
{
UITabBarController *tabController = (UITabBarController *)self.window.rootViewController;
RootViewController *rootViewController = (RootViewController *)[[[[tabController viewControllers] objectAtIndex:0] viewControllers] objectAtIndex:0];
rootViewController.managedObjectContext = self.managedObjectContext;
}
So you actually need a UITabBarViewController in the Storyboard and you can point to the UINavigationController if you want the ability to push other controllers.
You don't need other UINavigationControllers as I saw in your screenshot, as long as the rootviewcontroller is an UINavigationController.
You can add the UINavigationController as first of the tabs and then you can go and fill the other tabs with the viewcontrollers that you need displayed.
SO basically you need to create UITabBarController as rootviewcontroller.
Let me know if I understood your question correctly.
Here is an example of UITabBarController :
- (void)applicationDidFinishLaunching:(UIApplication *)application
{
//Here you set your controller
UIViewController* centerController = [[UIViewController alloc]init];
UINavigationController *navCenter = [[[UINavigationController alloc] initWithRootViewController:centerController] autorelease];
UITabBarController *tabBarController = [[[UITabBarController alloc] init] autorelease];
tabBarController.viewControllers = [NSArray arrayWithObjects:navCenter,nil];
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
self.window.rootViewController = tabBarController;
return YES;
}
Let me know if it worked.
You should have something like this :

Universal Master-Detail Application with Core Data and tab controller for iphone storyboard gets unrecognized selector sent to instance error

I started a Master-Detail Application in X-Code. I chose the options to be universal, core data, and git repo. When the application comes up, I went into the iphone story board, added a tab view controller, moved the nav/table/detail views it starts with to be in the tab controller as the third tab (in reality I want it to be the fourth). I then chose the tab controller to be the initial view the program should start with when in iphone mode. It builds successfully but does not allow the program to finish loading. The error that comes out is recorded below:
2013-05-11 21:35:00.302 FearlessAndThorough[6318:907] -[UITabBarController topViewController]: unrecognized selector sent to instance 0x1c592020
2013-05-11 21:35:00.306 FearlessAndThorough[6318:907] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UITabBarController topViewController]: unrecognized selector sent to instance 0x1c592020'
*** First throw call stack:
(0x337f33e7 0x3b4ee963 0x337f6f31 0x337f564d 0x3374d208 0xc9e43 0x35662aa1 0x35662625 0x3565a833 0x35602d1f 0x356027ad 0x356021ef 0x3731a5f7 0x3731a227 0x337c83e7 0x337c838b 0x337c720f 0x3373a23d 0x3373a0c9 0x3565946d 0x356562b9 0xc9ab5 0x3b91bb20)
libc++abi.dylib: terminate called throwing an exception
(lldb)
I am hoping that someone has done this before and can give me a little insight as to the proper procedure or steps to take when setting up a tab view controller type app that will then convert into a master detail application for ipad.
Here is the current app delegate's didFinishLaunchingWithOptions:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
UISplitViewController *splitViewController = (UISplitViewController *)self.window.rootViewController;
UINavigationController *navigationController = [splitViewController.viewControllers lastObject];
splitViewController.delegate = (id)navigationController.topViewController;
UINavigationController *masterNavigationController = splitViewController.viewControllers[0];
MasterViewController *controller = (MasterViewController *)masterNavigationController.topViewController;
controller.managedObjectContext = self.managedObjectContext;
} else {
UINavigationController *navigationController = (UINavigationController *)self.window.rootViewController;
MasterViewController *controller = (MasterViewController *)navigationController.topViewController;
controller.managedObjectContext = self.managedObjectContext;
}
return YES;
}
Your problem is that you added a tab bar controller to the front of your iPhone storyboard, but in your "else" clause you say the root view controller of the window is a navigation controller -- it's not, the tab bar controller that you added is. If you put a log in as the second line in that else clause, you will see that navigationController is actually a tab bar controller, not a navigation controller. That else clause needs to look like this:
UITabBarController *tbc = (UITabBarController *)self.window.rootViewController;
UINavigationController *navigationController = tbc.viewControllers[3];
MasterViewController *controller = (MasterViewController *)navigationController.topViewController;
controller.managedObjectContext = self.managedObjectContext;
I'm not sure about the "3" in tbc.viewControllers. I can't tell from your description which tab that navigation controller is in, so you might need to change that.
I think I got your problem.
Did you use a UITabbar object in the Xcode navigator :
Because to manage views with a TabbarController, the best way is to embed your view in a Navigation Controller, like below :
Then you got your first view embedded in a navigation controller :
You can now add a new viewController in the field and add it to the TabbarController by control-dragging from the TabbarController and select the Relationship item :
Then you got 2 views in a navigationController :
And nothing to do in the appDelegate.
Then do the last step for any other view you want embedded in the navigationController.
Hope this helps.
// Change your else part in appdelegate to this it may works.
else {
UITabBarController *tabBarController = (UITabBarController *) self.window.rootviewController;
// For third view in tabbar controller
UINavigationController *navigationController = [tabBarController viewControllers] objectAtIndex: 2];
navigationController = (UINavigationController *)self.window.rootViewController;
MasterViewController *controller = (MasterViewController *)navigationController.topViewController;
controller.managedObjectContext = self.managedObjectContext;
}

Resources