Maybe those are two different questions, but they basically ask the same thing.
I have a single view app, on my screen I have a Table View and a Collection View.
1) I want to provide a datasource (and delegate of course) for my tableview and for my collection view, but I don't want it to be in the same (main) ViewController file (in purpose of cleaner code). But the interface builder only allows me declaring as datasource (and delegate) the file's owner, which is the view controller. How can I do this? Is declaring programatically the right way? If so, where should it be done? Or, maybe, separating the datasources (and delegates) from the ViewController isn't the best practice?
2) In my table view's custom cells I have a button I wan't to deal with the button's actions in the same place (file) I deal with row selection (delegate obj). But once again the IB only let's me to connect the action to the custom cell class. How can I connect the action to another place?
Thank you for your answers in advance,
Dan
You should use the Object (the blue cube) from the object library. Drag and drop to the section (Documents outline) where your file's owner is present. Then in the identity inspector set it as the class (say Outsider) you want it to be. This will allow you to set Outsider object as the delegate/datasource and will also allow you to write IBAction's there.
The trick is to make that object(Class) visible in the xib by creating an object inside the xib (which will be done when the nib is loaded ).
And another thing, there is nothing wrong in setting the delegate or datasource programmatically, however through interface builder its much more convenient.
1) Do it programatically. Write your own delegate and assign it in code. Cleaner.
2) Connect the button's action in the ViewController class. That is clean, that's what view controllers are meant for. Turn on assistant editor and drag the "arrow" to the header file.
Question 1:
But the interface builder only allows me declaring as datasource (and
delegate) the file's owner, which is the view controller.
Question 2:
But once again the IB only let's me to connect the action to the
custom cell class. How can I connect the action to another place?
Both have same answer:
You can change the class by selectecing from interface builder.
Related
I have a single view aplicaition on xcode with several view controllers and xib files in it. I am trying to subclass a xib file's view controller called ViewControllerPg62 as a sub class of a view controller called ViewController. How can i do this?
Thanks in advance
Why are you working with XIB files? You should be using Storyboards.
I had to go back to an old project using XIBs to see how they worked.
In an XIB you should see an entry called "Placeholders", and under that, an item called "File's Owner." That represents the object that owns and manages the views in the XIB. Select that, and then display the Identity Inspector. There will be an entry at the top "Custom Class" where you can change the class that manages this view controller.
Before changing that, I suggest you create the source file for your view controller ("ViewController.swift", in your case.) Then when you change the class of the owning object, the XIB will create an instance of your custom class when that XIB is invoked.
The approach is quite similar for Storyboards, although it's a little more coherent.
I've followed the instructions in this answer to create a reusable custom UIView laid out with a xib, which I can embed in my Storyboard by referencing the custom class. This works well and I can successfully load the view as advertised. However I want my embedding view controller(s) to be able to connect to IBActions of my embedded view. In the linked example, the custom view receives its own actions but this seems like poor design. I've worked around this by creating a delegate protocol that for custom view, which forwards events to its delegate, but this feels like more work than should be necessary. Additionally, Interface Builder will not allow me to wire up the delegate using references in the UI so I must instead do it programatically.
What I really want is to create a custom IB Action in my custom view, like someActionHappened, then wire that up in the embedding view controller. What is the best way to accomplish this?
A .xib file has a File's Owner, which you can see and select when you're editing it.
When you load the nib, you get to specify the owner.
You can (and must) make the classes of these two things (the File's Owner in the nib and the actual owner at load time) match.
Thus, an action can be hooked from something in the nib to an IBAction in the File's Owner's class, and it will be fulfilled when the nib is loaded. Problem solved.
So:
However I want my embedding view controller(s) to be able to connect to IBActions of my embedded view
So the solution for you is to make your File's Owner (in your nib) and the actual owner (at nib-loading time) be your embedding view controller. Now your embedding view controller is allowed to have an IBAction and you can connect to it in the nib.
I want to launch a XLForms view controller as a Form Sheet. I want the controller to have a toolbar at the top and then the XLForm tableview underneath it. How?
The view controller isn't a navigation controller and so I need to add a toolbar at the top (or bottom) where I can add buttons. So how do I do this?
It turns out that this is not too difficult. I just wish that it was documented somewhere.
All the sample code I could find showed the top view controller inheriting from XLFormViewController. In this case, the IB controller only requires a topline view.
I wanted to expand the view controller to have other components in it other than just a "View" object. I wanted a toolbar across the top and a couple of other things.
So, here's how I did it. I'm not sure that this is the best approach but it did work.
Create the View Controller in IB and add all the components you want.
Include a TableView object someone in your design
Go into the "Assistant Editor" and hook the TableView object to the "tableView" object defined in XLFormViewController.h by ctrl-dragging and dropping on the IBOutlet tableView object.
All other controls work as usual.
Important:
Do not treat the tableView object like a regular object. In other words, do not implement UITableViewDataSource and UITableViewDelegate methods.
Hope this helps.
How should I go about creating a View for the storyboard programmatically? I want to access the labels from the first ViewController object made(automatically to call the IBAction methods of VC). I know that this first object of VC is the one linked to the view in the storyboard(?) and I need to change a label form another file, besides VC. I'm pretty sure the only way to do so would be to access the VC object that is linked to the view, or create one and not go with the default one that is created. If not, how would I go about accessing the labels of the view from another file?
You don't create storyboard objects programmatically. A storyboard is very basically an XML file Xcode uses to call different view controllers. The biggest advantage of using storyboards over NIBs is you can layout transitions or segues, and the advantage of NIBs or storyboards over initiating view controllers by code is obviously the visual interface. So your question doesn't really make sense.
If you want to reference a particular view controller's label from your storyboard you need to create a pointer to that view controller first, but changing it programmatically doesn't make sense because that's what storyboard is for.
That said you may just need to go look for your class name in your view controller's Identity Inspector in storyboard and then edit your label programmatically through an IBOutlet property.
I followed this UITabBarController Tutorial which creates a Tab Bar with according subviews mostly using Interface Builder. The UITabBarController is created there and the Tab's View Controllers are added there too.
Am I correct that creating the UIViewControllers {WelcomeViewController|AboutViewController}.{h|m} is unnecessary?
Who is the real File's Owner of the Subviews {WelcomeViewController|AboutViewController}.xib?
Note that I at first tried to create an IBAction method in WelcomeViewController.h: in Interface Builder at WelcomeViewController.xib, I could connect a button press to that action as it appeared at File's Owner. But at runtime it crashed, as the real File's Owner presumably is not an Object of WelcomeViewController.m. Am I right here? Is it a bug that the IBAction appears in Interface Builder (Xcode 4 here)?
A last question: How/can I still separate code (having IBActions in WelcomeViewController.h for actions that happen only on this subview) when I connect everything up in Interface Builder like in the tutorial?
Am I correct that creating the UIViewControllers {WelcomeViewController|AboutViewController}.{h|m} is unnecessary?
No, both controllers are necessary, since there should be at least (and, optimally, at most) one ViewController per full-screen window to manage your view hierarchy. The TabBarController is only a kind of "dumb" meta-controller managing the display of the sub-controllers it loads - therefore you need controllers for the views which are switched. I would recommend you read this part of the Apple doc.
Who is the real File's Owner of the Subviews {WelcomeViewController|AboutViewController}.xib?
The File's Owner should be the corresponding controller class (in your case, {WelcomeViewController|AboutViewController}.{h|m}) - you can set the class in Interface Builder in the inspector palette when File's Owner is selected. Only the very first window (usually called Main.xib or so) which is opened at application start should have the application delegate as File's Owner. File's Owners own the objects of the XIB/NIB file - object-reference wise, you know what I mean :) I think it should also be possible to load the XIB/NIB file with other controllers (and the other controller automatically becoming the File's Owner), but I'm not sure.
... Am I right here? Is it a bug that the IBAction appears in Interface Builder (Xcode 4 here)?
It may be that you wired up the action the wrong way in Interface Builder, a common mistake. Try holding the Ctrl key, then drag a line from the button onto the File's Owner, and choose the desired method to link to. That should do it.
A last question: How/can I still separate code (having IBActions in WelcomeViewController.h for actions that happen only on this subview) when I connect everything up in Interface Builder like in the tutorial?
I think I answered this in the first paragraph - WelcomeViewController is still there and all you have to do is create IBOutlets and wire them up in IB. Of course, you can also do the wiring programmatically, since the member "view" is automatically populated (via the File's Owner connection), and all subviews are accessible from there.