Set a UITabBarController delegate in a UIStoryboard - iphone

I've been searching for this, can't find the answer.
I'm setting up a UIStoryboard in Interface Builder, and while everything is working fine, I seem to be unable to hook up the delegate outlet of the UITabBarController to any of the UIViewController's in the UIStoryboard, regardless of their position in the UIStoryboard. I've set the UIViewController's to be a <UITabBarControllerDelegate> in the .h file, but Interface Builder won't allow me to select the UIViewController as the delegate for the UITabBarController.
Has anyone run into this issue?

It turns out that the reason you can't set the delegate in the UIStoryboard is because you have no guarantee that the UIViewController is loaded before the UITabBar is loaded. Therefore, programmatically setting the delegate (in a different UIViewController) is the ONLY way to accomplish this.

You'll need to do it programmatically in the application:didFinishLaunchingWithOptions method of your application delegate:
_tabBarController = (UITabBarController *)_window.rootViewController;
_tabBarController.delegate = self;

Related

Set the Delegate on SubView

I have a splitViewController that has a master and detail view controllers. The code below is from the master and it creates the new view in the detail:
UIViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:[NSString stringWithFormat:#"%#",[self.defaultSettingsMenuItems objectAtIndex:indexPath.row]]];
[self.detailViewController.view addSubview:controller.view];
detailViewController is a global instance of DetailViewController. In the detailViewController, I have many textFields and need to utilize the UITExtFieldDelegate. However, I think that the detailViewController isn't self at that point, and that's why I'm getting EXC_BAD_ACCESS errors on using the TextFieldDelegate methods in detailViewController.
EDIT: I have now found that the subView delegate methods only work for the viewController I setup as the rootViewCOntroller relationship from within Storyboard. Ex. If I have 6 views in the default menu settings above, whichever one I have setup as the first and root view in storyboard will work correctly. Any and all other subviews shown (from making a new selection in the master view) will not work properly. I think this will help diagnose the problem.
I am not familiar with storyboards, but I don't see you setting the detailViewController's delegate anywhere. You probably need to have something like self.detailViewController.delegate = self; somewhere before you yield control over to the subview.
This all I needed, the second line:
UIViewController *viewController= [self.detailViewController.storyboard instantiateViewControllerWithIdentifier:[NSString stringWithFormat:#"%#",[self.defaultSettingsMenuItems objectAtIndex:indexPath.row]]];
if (self.detailViewController.childViewControllers.count >= 1) {
NSLog(#"childViewControllers: %#",self.detailViewController.childViewControllers);
[[self.detailViewController.childViewControllers objectAtIndex:0] removeFromParentViewController];
}
[self.detailViewController addChildViewController:viewController];
[self.detailViewController.view addSubview:viewController.view];
EDIT: I've updated my answer with the if look to remove viewControllers from the stack. Slightly hacky, but functional.

UIView presented with Black screen, fix?

I call a View to be presented with the following code:
#import "infoView.h"
...
infoView *viewInfo = [[infoView alloc] initWithNibName:nil bundle:nil];
viewInfo.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:viewInfo animated:YES];
But when it is presented in run-time the view that is loaded turns out black.
Currently I am using storyboard, but I need to use this code, for it is a lot more efficient in my case, because I am dealing with multiple views!
It works fine if I connect it via StoryBoard.
I should be seeing 2 labels, 1 UITextView, and 2 UIButton.
The view was created using StoryBoard, when the .m and .h files for the view where created I did not add a .xib for it. And also it is linked through the "Custom Class" section in StoryBoard.
Thanks, hope someone can help!
It's generally pretty bad form to mock people who are taking the time and effort to help you.
Naming is important it makes your code easier to work with and allows other people to use it. Not following the conventions for the language you are working in is dangerous and means that your code is not compatible with other developers as things are interpreted differently.
If you look at the docuemntation for UIViewController you'll see this note in the initWithNibName:bundle: method description
If your app uses a storyboard to define a view controller and its associated views, your app never initializes objects of that class directly. Instead, view controllers are either instantiated by the storyboard—either automatically by iOS when a segue is triggered or programmatically when your app calls the storyboard object’s instantiateViewControllerWithIdentifier: method. When instantiating a view controller from a storyboard, iOS initializes the new view controller by calling its initWithCoder: method instead. iOS automatically sets the nibName property to a nib file stored inside the storyboard.
Therefore you are instantiating your controller wrong, the storyboard should be instantiating it. Which is done like this (naming corrected)
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:[NSBundle bundleForClass:[self class]]];
InfoViewController *infoViewController = [storyboard instantiateViewControllerWithIdentifier:#"InfoViewController"];
infoViewController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self infoViewController animated:YES];
Side note
infoView is a bad name for the class not only because you didn't start with a capital but also because it's completely deceiving. Anyone reading this would assume that InfoView is a subclass of UIView not UIViewController.

iOS - Interface Builder Outlets Not Initialized

I have created a view in Interface Builder with some labels and text as IBOutlets. I can view this screen perfectly when I segue to it from another view that I have defined in my Storyboard.
However, I have another XIB and an associated UIViewController that I want to access that view from. Because my XIB is not in the Storyboard, I cant segue to it. Instead I have to execute the transition programmatically.
PlantDetailViewController *plantDetailVC = [[PlantDetailViewController alloc] init];
[self.currentNavigationController pushViewController:plantDetailVC animated:YES];
When this code is executed it transitions to the view but the view is just blank. I have debugged the code and it enters viewDidLoad and viewWillAppear however all my IBOutlets are NIL....so nothing it showing up on screen!
Can anyone tell me why they might be NIL and how I can initialize them?
Thanks
Brian
It sounds like you're saying you have a PlantDetailViewController set up in your storyboard, and some OtherViewController that was created outside of your storyboard. Now you want OtherViewController to instantiate the PlantDetailViewController that was set up in your storyboard.
Let's say your storyboard is named MainStoryboard.storyboard.
First, you need to set the identifier of the PlantDetailViewController in your storyboard. You do this in the Attributes inspector, under the View Controller section. Let's say you set it to PlantDetail.
Then, in OtherViewController, this should work:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
PlantDetailViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"PlantDetail"];
[self.currentNavigationController pushViewController:vc animated:YES];
-init doesn't load a nib file for you, if you want to load a nib use -initWithNibName:bundle:
If you use nib naming conventions you can pass nil to load a nib whose name matches your class and the default bundle, i.e. [[PlantDetailViewController alloc] initWithNibName:nil bundle:nil], see the docs for -nibName for details.

can't add UIView from a UIViewController

I have some issue showing a view from a view controller. Basically, I have a UIViewController class, I programmatically created the view by overloading loadView method. Here is the code that I have:
UIView* view = controller.view;
UIWindow* window = [UIApplication sharedApplication].keyWindow;
if(!window)
{
window = [[UIApplication sharedApplication].windows objectAtIndex:0];
}
[window addSubview:view];
The view is not visible.
However, if I created a simple view based app by calling
[self presentModalViewController: controller animated: YES];
Everything works well.
I am new to the iOS View Programming. Anything I did was wrong?
Steve,
I'm not sure what you are trying to achieve here, but a typical iphone app will have a base UIViewController subclass, say a nav controller or tab controller and that controller's view is added as a subview of the UIWindow view in the appDelegate class.
You then instantiate further UIViewControllers or subclasses thereof and those views get added as subviews of the current view and so on.
Have you checked out the basic templates in XCode? These should show you how the appDelegate and the like works. You generally don't need to mess with UIWindow in other classes, in my experience.

UIView subviews don't responde to delegates

I have following code in viewDidLoad
myViewController = [[UIViewController alloc] initWithNibName:#"myView" bundle:nil] ;
self.myView = myViewController.view;
[self.view addSubview:myView];
This code loads view from myView.nib (I have corresponding view controller m and h files of course). myView view has UITextField and other controls. So far so good - I can see all my controls on the screen.
The problem however is that even though I set a delegate for UITextField to be File's Owner (which is myView) and I implement UITextFieldDelegate in myView.m, delegate methods are never fired!
This does NOT happen if I add UITextField to the original view (created by the XCode as default template). Why is this happening?
The reason I need to useSubview because in actual code will layer view to the UIScrollView so I can pan and zoom.
THanks!
My first question to your question is, "is there a reason to use UIViewController to load your NIB file?".
It appears that you're "throwing away" the UIViewController and merely using it for its ability to load a NIB file. I'd stop that first, as that may help you debug this issue. Use:
self.myView = (UIView*)[NSBundle loadNibNamed:#"myView"];
The second part I'd question is that you say "File's Owner" -- because you're using a separate UIViewController, you may have it set to call back to your UIViewController, not the code that you mean to callback to. Maybe you could tell us a little about the setup of the XIB file?