Xcode - How to connect XIB to ViewController Class - objective-c

I created first my TestViewController.h and *.m. Afterwards my TestView.xib.
Now I need to tell my xib: "Yes, please take the class TestViewController as my File's Owner".
I open up my xib, go to the Identity Inspector of its fileOwner and choose under "Custom Class" TestViewController.
But this seems not enough - as when I open up the TestView.xib, and then choose the "Assistent Editor View" it should bring up the corresponding ViewController on the right part of the split screen - in my case the "TestViewController.h". But it doesn't !
Is it necessary to bind the xib in any way to its viewcontroller by dragging lines to files like you do it with outlets and actions?

Click to select the xib. Now, select the file's owner. In the attribute panel on the right side, choose the third tab, "Identity Inspector". There is a header named Custom Class. Give your view controller's name there. After this, you can connect the elements with the file's owner.

I think I ran into exactly this situation when I created a UIViewController subclass but forgot to check "with .xib for UI" when I did it. Later, I went back and created the .xib separately.
Here's a more step-by-step way to associate your new UIViewController and .xib.
Select File's Owner under Placeholders on the left pane of IB. In the Property Inspector(right pane of IB), select the third tab and edit "Class" under "Custom Class" to be the name of your new UIViewController subclass.
Then ctrl-click or right-click on File's Owner in the left pane and draw a line to your top level View in the Objects portion of the left pane. Select the 'view' outlet and you're done.
You should now be able to set up other outlets and actions. You're ready to instantiate your view controller in code and use initWithNibName and your nib name to load it.

In the view controller create a "view" outlet (UIView) and mark it as IBOutlet. (When you use the correct defaults/patterns when creating the files within xcode, then this property should be there already.)
In Interface Builder create a link between the main view and the view property/outlet of the view controller/file's owner.
Just for the full picture: On creating/allocating the view controller, you should init it with the appropriate XIB file. This is the very moment, where the view controller object is bound to the view that is generated out of the XIB file.

1) First just like every one said give the view controller name in class of File's Owner
2) Select File's Owner drag a line from there to view this connects the both
3) Create an instance of View controller and add it to window to that the code snippet is as follows,
MyViewController *controller = [[MyViewController alloc] initWithNibName:#"MyView" bundle:nil];
4) Finally add the view controller's view as subview to window.TO do that that the coding is as follows,
[window addSubview:[controller view]];
Try the following snippet on appdelegate
- (void)applicationDidFinishLaunching:(UIApplication *)application {
// Override point for customization after application launch
[window makeKeyAndVisible];
MyViewController *controller = [[MyViewController alloc] initWithNibName:#"MyView" bundle:nil];
[window addSubview:[controller view]];
}
5) Use the following snippet to maximize the size of view to window so that no gape appears
[controller.view setFrame:[[UIScreen mainScreen] applicationFrame]];
Now you will see your view controller as you expected...
I hope this helps....

yes you have to add the view property to file owners of that view controller from interface builder:

choose your fileownr go to identity inspector window, and change class name of file owner to your view .h file, That will connect.

Updated Augustine's answer with Xcode 13.4.1 screenshot.
Follow the steps bellow:
Click to select the xib. Now, select the File's Owner.
In the attribute panel on the right side, choose the fourth tab "Identity Inspector". There is a header named Custom Class. Give your view controller's name or Custom Class Name there. After this, you can connect the elements with the File's Owner.

Related

Create a standalone view in storyboard to use programmatically

I'm trying to create and design a UIView using a storyboard but include it in a UIActionSheet programmatically. This is basically to avoid using CoreGraphics positioning functions with pixels
In old xcode I remember that it was possible to drag a UIView onto the nib without any controllers.
The view obviously has to be connected to the class, so it would have an IBOutlet, but not being added to the self.view
One thing that makes me feel like this should be possible is that if you drag a UIView into the controller black bar in storyboard it pops into place like so:
But its not shown on the screen itself. What is this feature for? Can I somehow open up this view and design it a bit?
Just create a new .xib file.
Right Click somewhere in the Navigator Area and select 'New File...'.
Select 'User Interface' from the list on the right and Select 'View'.
Click 'Next', 'Next', give your new view a name, and 'Create'.
A new .xib fill will be added to your project.
Double clicking on the new .xib file and it opens in Interface Builder (not Storyboard).
Edit/Design your View to your liking.
Then after you have your new view (.xib) in Interface Builder, it's a simple matter of creating a new subclass of UIView (ex. MyView), switching the class of your new view (.xib) to MyView, creating an instance of MyView in your controller, and adding it as a subview to your other view.
*And to answer your question about that little black bar at the bottom, it's called the 'Dock', and it's just a mini representation of the top-level documents of your scene. The dock is convenient for quickly dragging/dropping icons onto and making connections. See apple's storyboard description here. Ray Wenderlich has an easy to follow tutorial on storyboards here.
You cannot have a UIView outside of a UIViewController on a storyboard. I'm guessing it's because the storyboard would have no idea how to identify or instantiate with the current API. It is something I've had a use for myself. The solution is just use a XIB for the one UIView and load it up programmatically (just like used to do). I've found using a storyboard for most items and couple XIBs for re-usable views across multiple view controllers do work nicely together.
Here is some code I use to load a XIB as part of a custom object with the object gets initialized.
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
// Initialization code
[[[NSBundle mainBundle] loadNibNamed:#"BannerView" owner:self options:nil] objectAtIndex:0];
[self addSubview:self.view];
self.frame = self.view.frame;
}
return self;
}
As for dragging views down into the black bar on the storyboards. Those views are still part of the UIViewController, but they aren't a `subview' of the top level view. I think the document outline shows the hierarchy nicely.
The following view has 2.1.1 View, 2.1.2 View, etc outside of my main view hierarchy because they aren't subviews of my main view. The result is, they won't be displayed by default. I do have IBOutlets setup and I conditionally add/remove them from my main view hierarchy using the standard addSubview: and removeFromSuperview.

Replace the TableView in a SplitViewController

I am looking to replace the UITableView in the MasterViewController section of a UISplitViewController. Instead of the UITableView, I want just a View so I can place UIButtons, UILables, etc in it. These buttons would then control what is shown in the DetailView section of the SplitView.
I have asked this question one other place and someone suggested that I create a subclass of the UISplitViewController. This person didn't give much direction, besides retaining the DetailViewController.h, .m, and .xib and editing the MasterViewController.h, .m, and .xib to my liking.
Here are the steps that I have taken:
Created a new project and selected "Master-Detail Application"
Unchecked "Use Storyboard" so I could get at the xib files.
Opened "MasterViewController.xib"
Deleted the "Table View" under "Objects"
Added "View Controller" to "Objects"
Changed "#interface MasterViewController : UITableViewController" To "#interface MasterViewController : UIViewController" in "MasterViewController.h"
Commented out anything under "MasterViewController.m" that was causing problems because they were referencing properties of the TableView, which is no longer there.
Then I get this error: -[UIViewController _loadViewFromNibNamed:bundle:] loaded the "MasterViewController" nib but the view outlet was not set."
Am I on the right track? If I am, could someone help me out with the error I am getting?
Otherwise, if I am going at this wrong, could someone point me in the right direction?
Thanks!
now, with storyboard in the latest Xcode, here's what i have done …
create a new Master-Detail project, and allow storyboard
open MainStoryboard_iPad.storyboard
click on the TableViewController and then delete it
drag in a new plain ViewController
ctrl-click-drag from the navigation controller that is the master view controller to your new ViewController
remove the MasterViewController.h/.m files, and create a new class that is a subclass of UIViewController
take the name of your just created replacement class and place it in the Class name of the Custom Class section of your identity inspector
now, add buttons and wire up the way you want to. if you stick with a single view controller in the detail portion, you should be able to simply refer to the detailViewController directly and fill it as you want; for multiples, you can probably use replace segues.
for iPhone, the steps will be similar. you'll have to ctrl-click-drag from the nav controller to your new ViewController and set up the replacement ViewController.h/.m files in the same way. the segues from your buttons will be push segues, or you can simply call performSegueWithIdentifier:sender: .

Add subview using storyboard without external xib

I'm learning Objective-C.
I have a problem with new storyboard feature. I would initialize a subview inside a main view with xib.
Without using storyboard, I could do it using:
controller = [[UIViewController alloc]initWithNibName:#"NibName" bundle:nil];
[self.view addSubview:controller.view];
Now, I wouldn't use an external xib, but I want manage a view in a class and use it like a subview in another class.
I know that is possible use a xib and use a similiar code to load it, but it must be out the storyboard.
First create the view in your storyboard and then instantiate it with the following code. Also make sure you give it an identifier via the Attributes Inspector.
controller = [self.storyboard instantiateViewControllerWithIdentifier:#"identifier"];
[self.view addSubview:controller.view];
First create subview with design in some viewcontroller xib after that copy that view and paste in sub of ur viewcontroller in story board and give connections. Hope it will work.

Correct way to manually add a xib file

What is the correct way to manually add a xib file i.e. if while creating the class, we uncheck "With XIB for interface"...then how do we connect both the IB & VC.m file later, to ensure that the view gets loaded from xib ?
Typically this is done when you instantiate your sub-classed UIViewController. Your call would look something like this:
MyViewController *viewController = [[MyViewController alloc]
initWithNibName:#"NibName" bundle:nil];
Checkout UIViewController initWithNibName: bundle: documentation for more details. You can also look at the documentation on Custom View Controllers for a good bit of information on sub-classing UIViewControllers.
To allow setting actions and outlets at design time in IB, once you create the xib file, change File Owner to your controller class. To do this, in IB, with File Owner selected, press Command-4.

Accessing Views created in Interface Builder

I've created a ChildViewController class, and then a nib that uses that class.
Then I created a BaseView, that includes some buttons, and some text that I'll be changing programmatically.
Then I created two more views (Boy and Girl), that I want to be able to lay behind the baseview so that the background color is different along with some graphics in an ImageView. I've named the views that I created in IB 'Boy' and 'Girl'...
But when I go back to my code where I'm calling ChildViewController, I'm not sure how to access the views I created so I can call insertSubView. Do I need to instantiate them in code? (in ViewDidLoad perhaps?) Does the nib create the instances when it loads?
I'm confused about how to handle multiple views for a single ViewController
edit =================
#Pablo Santa Cruz
Your answer assumes that i have two nibs and two view controllers (one for each view). I want to know if I can use one nib and one controller, and load in UIViews. It seems silly to create another nib and controller, when all want to do is change the background color and some graphics. Can't I programatically load in UIViews into a UIViewController?
Add IBOutlets in your App Controller class in Xcode then link them in IB (ctrl-click or right-click) from the connections tab in the Inspector to the object.
Then you will be able to send method calls to the objects.
The code in Xcode should look like this:
#interface AppController : NSObject
{
IBOutlet Girl girlIvarName1;
IBOutlet Boy boyIvarName2;
}
#end
You can access a UIView programatically by assigning a value to its tag property, which can be set in IB on the first tab of the inspector (Command 1)
The tag value defaults to zero, so if you want to access it specifically, make it non zero and unique. e.g. 100, which I will use in the example code below
Once the tag is set you can access the view using the following code in your UIViewController that was initWithNibName for the NIB containing the tagged view
UIView *aView = [self.view viewWithTag:100];
You can get instances for your IBuilder views with this piece of code:
boyViewController = [[BoyViewController alloc] initWithNibName:#"BoyViewController" bundle:nil];
girlViewController = [[GirlViewController alloc] initWithNibName:#"GirlViewController" bundle:nil];
Assuming your NIB file names are BoyViewController and GirlViewController. With those instances, you can do whatever you need to. I.E., adding them to a parent view (with addSubView message on the parent).