UITabBarController viewControllers strange behavior - ios

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!

Related

Pass NSString value to another ViewController in Objective C

I am trying to pass NSString value to another ViewController. But I get null instead of the value. Here is my code.
FirstViewController.m:
NSString cellID = #"66";
SecondViewController *apiViewController = [[SecondViewController alloc] init];
apiViewController.strMessage=cellID;
[self.navigationController pushViewController:apiViewController animated:YES];
SecondViewController.h:
#interface SecondViewController : UIViewController{
NSString *strMessage;
}
#property(nonatomic,retain) NSString *strMessage;
#end
SecondViewController.m:
#implementation SecondViewController
#synthesize strMessage;
NSLog(#"%#", strMessage);
#end
I did import. I assigned variable before pushing. But it anyway returns null. How can I do this? Any tips, ideas. Thank you.
Try assigning the property before you push the view controller.
NSString cellID = #"66";
LineChartViewController *apiViewController = [[LineChartViewController alloc] init];
apiViewController.strMessage=cellID;
[self.navigationController pushViewController:apiViewController animated:YES];
Furthermore, you need to call the NSLog from within a function in your implementation. The viewDidLoad function, for example, as this is a UIViewController that is being pushed on a UINavigationController stack.
try this code
SecondViewController *apiViewController = [[SecondViewController alloc] init];
apiViewController.strMessage=cellID;
[self.navigationController pushViewController:apiViewController animated:YES];
Try this
SecondViewController *apiViewController = [[SecondViewController alloc] init];
apiViewController.strMessage=cellID;
[self.navigationController pushViewController:apiViewController animated:YES];
And Print
NSLog(#"%#", self.strMessage);

TabBarController returns null

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;

UIView added programmatically to UITabBarController displays just black

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];
}

Accessing UIScrollView from other ViewController

I have a viewcontroller, if I press a button, another viewController is loaded, but the first is not unloaded. I want to access a variable form the first view controller from the second, actually a UIScrollView, so that I can use it in this way:
scroll1.hidden = YES;
How can I do this? I tried importing the .h file, but still I cannot use the UIScrollView
EDIT:
NSArray* stack = [self.navigationController viewControllers];
NSInteger currentIndex = [stack indexOfObject:self];
ViewController* linkToA = (ViewController*)[stack objectAtIndex:currentIndex - 1];
[linkToA.scroll1.subviews makeObjectsPerformSelector:#selector(removeFromSuperview)];
[linkToA.scroll1 addSubview:linkToA.backgroundImage];
or
ViewController *linkToA = [[ViewController alloc] init];
linkToA = (ViewController*)self.presentingViewController;
[linkToA.scroll1.subviews makeObjectsPerformSelector:#selector(removeFromSuperview)];
[linkToA.scroll1 addSubview:linkToA.backgroundImage];
just make sure first view controller does have a property of your scrollView in the header:
#property (nonatomic, strong) UIScrollView *scrollView;
if you don't have a latest xcode put #synthesize scrollView to the implementation of the first controller
lets say your first controller is A and the second is B
if B is a added as a modal then use this:
linkToA = (A*)B.presentingViewController;
if B is added to navigationControllerStack:
NSArray* stack = [B.navigationController viewControllers];
NSInteger currentIndex = [stack indexOfObject:B];
linkToA = (A*)[stack objectAtIndex:currentIndex - 1];
after you have a linkToA you have to do
linkToA.scrollView.hidden = YES;
hope this will help

UISplitView in UIViewController

Hi I am working With Ipad Application
I want to Add UISplitView to UIViewController and it Should be in Programmatic approach
Can Any one help me how to get out of this
i have added split view to the UIWindow and Worked Fine ,But i need to add UISplitView to UIView Controller,
when the User Taps a button in Main Screen it goes to detail View and the detail view should be UISplitView
Thx in Advance
I would suggest MGSplitViewController. It has a similar API to the regular, but with many extras. One of which is ability to add it as subview.
Hi I made it as below it may help you.Just pass parameter as described and you can get slpitview as you desired.
.H file
#import <Foundation/Foundation.h>
#class AppDelegate;
#interface CustomSplitView : NSObject
{
AppDelegate *objAppDelegate;
}
+(UIView *) setSplitView : (UIViewController *)masterView : (UIViewController*)DetailView :(CGRect)frame;
+(void) changeSplitView:(UIViewController *)DetailView :(UINavigationController *)navigationController;
#end
.M file
#import "CustomSplitView.h"
#import "AppDelegate.h"
#implementation CustomSplitView
//*********this return view addsubview on self.view
+(UIView *) setSplitView:(UIViewController *)masterView :(UIViewController *)DetailView :(CGRect)frame
{
objAppDelegate=(AppDelegate *)[[UIApplication sharedApplication] delegate] ;
objAppDelegate.objMasterView=masterView;
objAppDelegate.objDetailView=DetailView;
//Select navigation for every split view
UINavigationController *masterNavigationController = [[[UINavigationController alloc] initWithRootViewController:objAppDelegate.objMasterView] autorelease];
UINavigationController *detailNavigationController = [[[UINavigationController alloc] initWithRootViewController:objAppDelegate.objDetailView] autorelease];
;
objAppDelegate.objSplitView.delegate=objAppDelegate;
objAppDelegate.objSplitView.viewControllers = [NSArray arrayWithObjects:masterNavigationController, detailNavigationController ,nil];
objAppDelegate.objSplitView.view.frame=frame;
return (objAppDelegate.objSplitView.view);
}
+(void) changeSplitView:(UIViewController *)DetailView :(UINavigationController *)navigationController
{
objAppDelegate=(AppDelegate *)[[UIApplication sharedApplication] delegate] ;
UINavigationController *detailNavigationController = [[[UINavigationController alloc] initWithRootViewController:DetailView] autorelease];
objAppDelegate.objDetailView=detailNavigationController ;
// Update the split view controller's view controllers array.
// NSArray *viewControllers = [[NSArray alloc] initWithObjects:navigationController, objAppDelegate.objDetailView, nil];
// objAppDelegate.objSplitView.viewControllers= viewControllers;
objAppDelegate.objSplitView.viewControllers = [NSArray arrayWithObjects:navigationController, objAppDelegate.objDetailView ,nil];
}
#end
for set split in your home view
Masterview *objFirstView = [[Masterview alloc] initWithNibName:#"Masterview" bundle:nil];
appdel.masterDelegate = objFirstView;
Detailview *objSecondView = [[Detailview alloc]
initWithNibName:#"Detailview" bundle:nil];
UIView *objView=[CustomSplitView setSplitView:objFirstView :objSecondView :self.view.frame];
[self.view addSubview:objView];
[objFirstView release];
[objSecondView release];

Resources