Correct way to manually add a xib file - objective-c

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.

Related

iOS subview widget hooked up to multiple controllers

So, I want to create a reusable widget as a xib and subview that can appear on a set amount of specific screens. This widget will have three buttons, each with an Action.
I want to be able to handle these actions on multiple viewcontrollers.
So say ViewControllerA, ViewControllerD, and ViewControllerF can handle the three button events, each in their own way.
I've created the nib file. How do I import it into the specific viewcontrollers, and then how do I wire up those events?
EDIT: I know that I could potentially get outlets set up via a viewcontroller, but Apple states that UIViewController is for full-screen views only, and my widget is only taking up a small portion of the screen.
You have done correctly. And one thing is, In iOS it's not widget.It's a UIView.
(Sorry there may be any typo in my code.I have written myself in StackOverflow)
Follow Below Steps to finish it..
1) After you have created the xib for the view, then you need to have a UIView subclass files.. For example your xib name likes this CustomView.xib means then create a files like this CustomView.m and CustomView.h
2) In your CustomView.xib , You need to set the fileOwner as your CustomView.h.
3) In your CustomView.m file, there will be a method like initWithFrame: In that method you need to load your xib file like this
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"CustomView" owner:self options:0];
UIView *currentView = [topLevelObjects objectAtIndex:0];
[self addSubView:currentView];
4) Almost over. In any of your view controller, you can use this xib like
CustomView *newSubView = [[CustomView alloc]initWithFrame:CGRectMake(0,0,55,67)];
[self.view addSubView:newSubView];
That's it.. Go on..
You have created a nib file but make sure that you have also created the .h and .m file that will be the controller for that nib file. You will have to look up how to implement delegate methods which your other view controllers can capture and act on in their own way. Here is a great tutorial to get you started on making custom classes with custom delegates: Link

Xcode - How to connect XIB to ViewController Class

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.

initWithNibName VS viewDidLoad

I've been trying to understand for hours when I should use the viewDidload: and when I should use initWithNibName: to set up the properties of my viewController.
For instance, I'm using a TableViewController and I'm setting all its properties (such as the backgroundColor, the separateColor, the toolbar items) in initWithNibName. It is the right way to do ?
If somebody could enlighten me.
Thanks
You should set up your properties in the viewDidLoad. This method is called by the system when the controller's view is loaded into memory. The initWithNibName: is something that you call when you create a controller instance from a nib file.
That is to say, that if you set up your properties in the initWithNibName: and instead you call init, your controller might not be in a good state; thus, it's best to do in viewDidLoad.
You should use viewDidLoad: method of your controller. To quote from Apple's documentation on initWithNib:
The nib file you specify is not loaded right away. It is loaded the first time the view controller’s view is accessed. If you want to perform additional initialization after the nib file is loaded, override the viewDidLoad method and perform your tasks there.
initWithNibName: is called when the NIB is loaded and instantiated.
viewDidLoad: is called when your view is actually presented onscreen.
And yes - I believe that in your case, setting colors and such are best done in initWithNibName

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.

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).