Having issues understanding views and view controllers inside a storyboard - ios

I have issues understanding how the view inside the storyboard is targeted.
http://imageshack.us/photo/my-images/27/uye0.jpg/
Here is an image of a storyboard containing 2 view objects (Correct me if I am wrong).
Now, I want to change the background color of one of the views, to my understanding I do this like this:
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.view.backgroundColor = [UIColor redColor];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
If this is implemented in to the project that I linked above, this does nothing. The "viewDidLoad" never executes to my understanding.
The only view controller is named viewController, so my question is, how do I make viewControllers for both of the views? And how do I distinguish between the views when creating the view controllers?
And what identifier is used for this?
EDIT 1
I added
NSLog(#"Here") after viewDidLoad, and it does execute, but it never changes the background color of the view

You need to create a new objetive C class to contain the new view controller and then link that class to the other view in the storyboard:
http://i.stack.imgur.com/UHNvs.png

Related

UIViewController loading another view controller via xib, trying to access the default view causes crash

So, I have this problem, that should be trivial.. I have a View Controller that is loading another view controller from a xib. Trying to reference the view of that secondary view controller crashes with :
'NSInternalInconsistencyException', reason: '-[UIViewController _loadViewFromNibNamed:bundle:] loaded the "Embedded" nib but the view outlet was not set.'
*** First throw call stack:
(
0 CoreFoundation 0x000000010689134b __exceptionPreprocess + 171
The code snippet that does this looks like this:
- (void)viewDidLoad {
[super viewDidLoad];
// loads controller just fine.
EbeddedViewController *embedded = [[EbeddedViewController alloc] initWithNibName:#"Embedded" bundle:nil];
// KABOOM on line below
UIView *embeddedViewIs = embedded.view;
}
The EmbeddedViewController extends UIViewController, and it's very ordinary/plain..
#import "EbeddedViewController.h"
#interface EbeddedViewController ()
#property (nonatomic, strong) IBOutlet UILabel *embeddedLabel;
#end
#implementation EbeddedViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
#end
This is very boring and ordinary:
And this is the default view - I have tried adding an IBOutlet for it, but it crashes none-the-less.
The xib view controller is set up with the custom class properly:
I have no clue why this crashes.. If you wish to try this little app, please download it here:
Link to a tiny two view controller app where this crash is demonstrated
If you want to make the controller's view by using a xib, you shouldn't add a controller to the InterfaceBuilder, just add a view.
Select the File's Owner and set the custom class (EmbeddedViewController)
Connect the File's Owner's view outlet to the newly created view by control dragging from the File's Owner to the view as seen on the image

Checking when a TabBar item is clicked - Objective C

I have a ViewController with 2 sub containers. The first sub container points to a ViewController with a TabBar inside it. The second sub container is a ViewController that contains a collection view. Now my issue is trying to access the first sub containers TabBar so that when an Item is clicked, I can know which item is clicked and process my data.
The main ViewController has a class. All the other sub containers for that ViewController also have a class. Here is the .h for my sub container with the Tab Bar:
#import <UIKit/UIKit.h>
#interface home_tab : UIViewController <UITabBarControllerDelegate>{
}
#end
.m:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
-(void) tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
{
NSLog(#"working");
}
Now when clicking on the Tab Bar that is populated, didSelectViewController is never called.
I am using storyboard.
Suggestions and thoughts?
Try this on your viewDidLoad
- (void)viewDidLoad
{
[super viewDidLoad];
[[self tabBarController]setDelegate:self];
// Do any additional setup after loading the view, typically from a nib.
}
It's just an suggestion :)
[[self tabBarController]selectedIndex] This will return the index of the selected tab.
I think you have a couple problems atleast from what I can see here,
You are using a TabBar inside of a ViewController, not a UITabBarController, thus you need to use UITabBarDelegate not UITabBarControllerDelegate. You will have to manage the view controllers or whatever view you will want to be loaded on your own most likely with the delegate callback:
-(void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item;
Also you dont have a UITabBar defined in your controller, therefore your ViewController has no idea you have a UITabBar in your Storyboard. You need something like this:
#interface ViewController : UIViewController <UITabBarDelegate>
#property (weak, nonatomic) IBOutlet UITabBar *tabBar;
#end
Then you will need to Control drag from the ViewController to your UITabBar and back to connect the Delegate in your Storyboard.
Id recommend using a UITabBarController so you dont have to manage the views yourself depending on what you are trying to accomplish.
Hope this helps!
the didSelectViewController method is part of the UITabBarControllerDelegate Protocol and is called on the UITabBarController's delegate. Did you set the delegate of the tab bar controller to the current instance of your subcontainer? Inside ViewDidLoad: do something like this:
[self.tabBarController setDelegate:self];
You can also set a delegate on the UITabBar rather than the controller, and the UITabBarDelegate Protocol contains a method tabBar:didSelectItem: that would be called.

How to load another View when loading a ViewController

I have a ViewController it has 3 views. What I want to do is without loading the default view when loading the ViewController, load other view of the same ViewController (rarther than load the main view)
IS this possible. Then how I can do that?
Thanks
You'll have to call the addSubView method of the UIView class.
So, when your initial view loads in the viewDidLoad method of your UIViewController, you add another sub view to it.
[self.view addSubView : YOUR_CUSTOM_VIEW_HERE];
You have to give more precise description of your problem.As when you talk about a view, it can be a view like UIButton which can be added like
[Self.view addsubview:yourView];
But if you have created that view in some other custom class which is subclass of UIView ,then in your viewController.m
- (void)viewDidLoad
{
obj =[[customView alloc] init];
self.view =obj;
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
Where customView is a subclass of UIView whose view you wan't to load, not the view of the original viewController file.
What you are doing over here is that when the viewDidLoad method is called , you change the view of that viewController to view of the customView (subclass of UIView).
(adding view as addSubview is best option I think)

Overriding loadView causes viewDidLoad and loadView to fire everytime a VC appears

My view heirarchy sits on several custom "root" UIViewController subclasses. I'm trying to set a custom self.view for one of my root VC subclasses. There, I am doing:
MyRootViewController_With_Scroll.h
// Import lowest level root VC
#import "MyRootViewController.h"
// my custom scroll view I want to use as self.view
#class MyScrollView;
#interface MyRootViewController_With_Scroll : MyRootViewController {
}
#property (strong) MyScrollView *view;
#end
MyRootViewController_With_Scroll.m
#import MyRootViewController_With_Scroll.h;
#interface MyRootViewController_With_Scroll ()
#end
#implementation MyRootViewController_With_Scroll
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)loadView
{
NSLog(#"loading view");
CGRect windowSize = [UIScreen mainScreen].applicationFrame;
MyScrollView *rootScrollView = [MyScrollView scrollerWithSize:windowSize.size];
self.view = rootScrollView;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
// Getter and setter for self.view
- (MyScrollView *)view
{
return (MyScrollView *)[super view];
}
- (void)setView:(MyScrollView *)view
{
[super setView:view];
}
According to the iOS6 docs, viewDidLoad in only suppose to fire once per view controller for the entire lifecycle of the app.
What am I doing wrong here? What is causing my view controllers to repeatedly call loadView/viewDidLoad? Strangely, my apps "home screen" VC loads the view just once, but all its subsequent views in the navigation heirachy fires loadView everytime they appear. What is going on?
edit I've changed the property to strong. Same issue happens.
edit 2 I've stopped overriding loadView and its still happening. Now I'm really confused.
This is expected behaviour. If you're popping view controllers off a navigation stack, and nothing else has a reference to them, then they're going to get deallocated. Therefore when it appears again, it will be a new instance, so it has to perform loadView and so on all over again. Include self in your logging, you should see that it is a different object each time.
You've also redefined the view controller's view property as weak - if you are re-using the view controller objects, then this will be nilled out as soon as the view has no superview.
Prior to iOS 6, a view controller that was mid-way in your navigation stack would get its view unloaded under memory pressure:
root --> VC1 --> VC2
VC2 is on screen, a memory warning is received. VC1 would unload its view. When you pop VC2 off the stack, VC1 would call loadView again. This no longer happens.
However, if you've popped back to VC1, and nothing has a strong reference to VC2, then VC2 is deallocated. When you push another VC2 onto the stack, this is a new instance and loadView will be called again. Presumably you are creating these new instances of VC2 in code, so you should be able to tell that you are creating a new instance.
Thats because you have weak view property. So it get realloced all the time. Also, I don't think that you need to override view property at all.

Load UITableViewController programmatically and add view as subview

I want to load a UITableViewController inside a UIView because I want to change the view on button click (like UITabBar but with my own buttons). I'm using a storyboard and have defined a TableViewController with custom class "InitialTableViewController" and identifier "InitialView".
My code look like this:
#import "MyViewController.h"
#import "InitialTableViewController.h"
#interface MyViewController ()
#end
#implementation MyViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
InitialTableViewController *tableControl = [self.storyboard instantiateViewControllerWithIdentifier:#"InitialView"];
[[self view] addSubview:[tableControl view]];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
#end
The view starts and I can see my table but the code inside "InitialTableViewController" doesn't work.
What can I do?
Well, it would be easier to just have a normal UIViewController with a UIView as root of the Nib and then put a UITableView. My answer is based on your need to have buttons on that UIView.

Resources