I have a tabbarcontroller in storyboard as initial view controller
How does this return null
UITabBarController* tabbarController = (UITabBarController*) self.tabBarController;
NSLog(#"%#",tabbarController);
NSLog(#"%#",self.navigationController.tabBarController);
Originally what I am trying to do
NSMutableArray *newTabs = [NSMutableArray arrayWithArray:[self.tabBarController viewControllers]];
NSLog(#"\n\n\n%lu\n\n\n",(unsigned long)[newTabs count]);
NSLog(#"self.tabBarController.viewControllers %# \n\n",self.tabBarController);
[newTabs removeObjectAtIndex: 1];
[self.tabBarController setViewControllers:newTabs];
Why am I getting null?
The reason null is returned, is that self is your UITabBarController, therefore, it doesn't have anything on self.tabBarController
Your code should look like this:
NSMutableArray *newTabs = [NSMutableArray arrayWithArray:[self viewControllers]];
NSLog(#"\n\n\n%lu\n\n\n",(unsigned long)[newTabs count]);
NSLog(#"self.viewControllers %# \n\n",self);
[newTabs removeObjectAtIndex: 1];
[self setViewControllers:newTabs];
In Swift
let indexToRemove = 1
if indexToRemove < (self.viewControllers?.count)! {
var viewControllers = self.viewControllers
viewControllers?.remove(at: indexToRemove)
self.viewControllers = viewControllers
}
directly use self in UITabBarController class, not self.tabBarControllers.
Check out Joe's Answer self.tabBarController is NULL
If you have a navigation controller you need to add this to your YourTabBarViewController.h file
#property (nonatomic, retain) UITabBarController * myTabBarController;
Then in YourTabBarViewController.m file in viewDidLoad just assign it to self and add the delegate
self.myTabBarController = self;
self.myTabBarController.delegate = self;
Related
guys, I need your help with ObjectiveC and UITabBarController.
I have 2 pieces of code with the same (I hope) functionality. But works only second one. The task is to dynamically create array of viewControllers and assign it to UITabBarController viewControllers property.
I have DZCustomTabBarController that inherits from UITabBarController.
#interface DZCustomTabBarController : UITabBarController
#end
and property #property (nonatomic, strong) NSMutableArray *controllers; that points to my dynamically created viewControllers like that.
Everything is happening in viewDidLoad method
Code below doesn't work
NSArray *titles = #[#"first", #"second"];
for (NSString *title in titles) {
DZViewController *controller = [[DZViewController alloc] init];
controller.title = title;
[self.controllers addObject:controller];
}
self.viewControllers = self.controllers ;
and I can't figure out why.
But this piece of code works.
DZViewController *firstViewController = [[DZViewController alloc] init];
firstViewController.title = #"first";
DZViewController *secondViewController = [[DZViewController alloc] init];
secondViewController.title = #"second";
self.viewControllers = #[firstViewController, secondViewController];
I'm not advanced at Objective C so I need your help. I think that problem in this line of code [self.controllers addObject:controller];
I think, your controllers property is used uninitialized. Try doing self.controllers = [NSMutableArray array]; before using your for-in cycle. Good Luck!
I have a view controller say 'HomeViewController' on which I have added a UITabBarController, which has 4 UITabBarItems. Now what I want is, when I select the HomeViewController no tab should should be selected for the first time and another view should be loaded. I have tried UITabBar instead of UITabBarController but its not working. I have also tried :
tabBarController.selectedViewController=nil; //giving crash
tabBarController.selectedIndex=-1; //not working either
UITabBarItems should be selected when user will click on them.
You have to add UITabBar object on HomeViewController.
In ViewDidLoad you have to add following code:
ViewController1 *controller1 = [[ViewController1 alloc] initWithNibName:#"ViewController1" bundle:nil];
ViewController2 *controller2 = [[ViewController2 alloc] initWithNibName:#"ViewController2" bundle:nil];
viewControllersArray = [[NSArray alloc] initWithObjects:controller1,controller2, nil];
tabBarController = [[UITabBarController alloc] init];
tabBarController.viewControllers = [[NSArray alloc] initWithArray:viewControllersArray];
for(int i = 0; i < tabBarController.tabBar.items.count; i++){
[[tabBarController.tabBar.items objectAtIndex:i] setTitle:[[tabBar.items objectAtIndex:i] title]];
}
isItemSelected = NO;
Also set the tag of tab bar items starting from 0. As 0 for first item, 1 for second item and so on.
and implement delegate method:
(void)tabBar:(UITabBar *)tabBar1 didSelectItem:(UITabBarItem *)item{
if(!isItemSelected){
isItemSelected = YES;
AppDelegate *appDel = (AppDelegate *)[UIApplication sharedApplication].delegate;
appDel.window.rootViewController = tabBarController;
}
tabBarController.selectedIndex = item.tag;
tabBarController.selectedViewController = [viewControllersArray objectAtIndex:item.tag];
}
I think this is not the right way, as Concept of creating TabBar says that " Show the particular controller of related tab". If u do not select any tab than what else you will show on screen, "A black screen ?". so please re-architecture your design.
I am programmatically changing the tab bar item for my tab bar at runtime.
The whole UI of my app uses Storyboards and this is the only area where I am making the UI changes in code.
So, the UI changes depending on a property. If this property cannot be found, the array of viewControllers changes to the new array that contains the new UIView.
Here's my code for the TabBarController.m:
NSArray *arrayOfControllers = self.viewControllers;
NSMutableArray *newArrayOfControllers = [[NSMutableArray alloc]init];
for (id controller in arrayOfControllers)
{
[newArrayOfControllers addObject:controller];
}
if ( !isMember)
{
NotMemberVC *vc = [[NotMemberVC alloc]init];
vc.tabBarItem = [[UITabBarItem alloc] initWithTitle:#"Test" image:[UIImage imageNamed:#"door-sign.png"] tag:0];
[newArrayOfControllers removeLastObject];
[newArrayOfControllers addObject:vc];
self.viewControllers = newArrayOfControllers;
}
And here's what it looks like when I select this new tab bar item:
Any suggestions as to how I can fix this?
First of all you don't need to do a for cycle when you have a method to do a mutableCopy of the array:
NSArray *arrayOfControllers = self.viewControllers;
NSMutableArray *newArrayOfControllers = [arrayOfControllers mutableCopy];
then here, you was not initializating the viewController with the view. In this case you have your VC with the UIView in your storyboard, and so you have to choose a StoryboardID in your VC in the Storyboard, and then:
if ( !isMember)
{
NotMemberVC *vc = [self.storyboard instantiateViewControllerWithIdentifier:#"Your_Identifier_ViewController_Storyboard"];
vc.tabBarItem = [[UITabBarItem alloc] initWithTitle:#"Test" image:[UIImage imageNamed:#"door-sign.png"] tag:0];
[newArrayOfControllers removeLastObject];
[newArrayOfControllers addObject:vc];
//Here make a copy to come back to immutable array
self.viewControllers = [newArrayOfControllers copy];
}
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];
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.