How to make a derived UITableVIew work - iphone

I've made a new class in my Xcode project which is derived from UITableView
I then drag a UITableView from in the interface builder onto my view and change the class of the object to my derived class. Then I drag the outlet from the table to the files owner and hook it up to an outlet variable in my main view, which is of the same type as my derived class.
How do I also set up the datasource and delegate so that they belong to the derived class?
I've got two table views on my main viewcontroller, and one of them uses that controller itself which works fine. The delegate and datasource is the file owner of the view controller.
But my other table view will be for different data, so I want it to use the datasource and delegate which is implemented on my derived tableview.

When you click on the UITableView-derived object are you not able to see the delegate and datasource members under the Table View Connections pane of the Inspector window? It should be as simple as dragging a connection from each to file's owner, or whatever object you want to make delegate/datasource. I've seen them go away when all you do is change the class type of an object, but if you write headers and make sure your class says that it is derived from UITableView then return to IB I believe you will see them again.
(apparently IB2 used to handle this the way you expected - in IB3 it is best to derive in Xcode first, then use the derived class in IB)

Related

Adding a TableViewController to an existing table view

I've got a Table view and it's the child of the View ( see the IB hierarchy ) :
I want to start customizing the tableCells, so I assume I'll have to add a tableViewController . Where would I start in this instance ? the TableViewcontroller can't be a child of the MainViewController, can it ?
Cheers,
You would need to add a table view controller at the top level.
Then drag connections from the table to the controller of datasource and delegate
Then drag connections from the controller to the view for "view"
Then change the class of the controller you added (it's the last tab in the inspector) to your custom UITableViewController class (if you don't subclass it it does nothing)
Then make sure that you somehow retain the controller when the nib is loaded. Easiest way is with an IBOutlet in the file's owner.
Sorry if this is a bit general, but the specifics would consume pages. I don't recommend this approach unless you have some experience with this and know what most of the above means, in which case it's possible and sometimes desirable to do this, and good job if you do.
The easiest method, if you just want a simple table view, no special circumstances, is to use the File>New File>UITableViewController with xib for user interface, then go from there with the file it makes, but that isn't your question, so I have answered as best I can.
It would be easier to build a tableViewController class with a table inside that and add the tableViewController to the view instead of reverse-engineering it. The tableViewController will have all your delegate and datasource functions for your table fairly mapped out so you can move whatever you already have into those functions.
As for custom tableViewCells, here's a great tutorial from pragmaticstudio.com on how to do so. He walks you through all the aspects of building a tableViewController and also how to customize your cells in IB.

How can I populate UITableView with XML?

I have a tab bar application. In one of my tabs, there is a search bar and a table view below that. When you enter something into the search bar, it returns parsed xml. I need to put this parsed information into the tableview below. The class inherits from UIViewController. I declared a UITableView object in the header file and linked it in interface builder, and adopted the UITableViewDelegate protocol.
I'm not sure If i'm going about this the correct way. Any help?
That sounds about right. You will need to also have your UIViewController implement UITableViewDataSource, and add the methods from that protocol to populate the table.
There are various tutorials available which guide you step-by-step to create a simple tablview. Google them. You can follow these steps for connecting your tableView outlets:
Select your viewController where you are displaying the tableview to be your "File's Owner" in Identity Inspector.
Drag your view's outlet to your File's owner.
For tableView inside view, drag its outlets to File's owner again so that your datasource and delegates are up. And in the same view, drag your referencing outlet to the IBOutlet you have created in your viewController class.

Loading a View from IB

This should be a pretty easy fix, but I haven't figured out from reading the Apple documentation or other SO questions how to do this simple switch from creating my Interface programmatically to using Interface Builder.
I am basing my code around this framework:
http://www.pushplay.net/blog_detail.php?id=27
The only difference is that, where each View is programmatically created (View01.m, View02.m) in ViewDidLoad, I instead want to import from a nib (while still using this framework) for each view (each view has a unique IB design).
Thanks for the help.
Think of IB as an Object Creator and not a code generator. That really helps. What IB does is actually create instances of objects as they are dragged on to the desktop/view/XIB window. It then allows you to start creating various connections (with a control drag on the mouse) from one object to another object. You then instantiate the entire XIB by unarchiving it from your bundle. This is highly automatic and reading up on UIViewController should move you along a bit. Look at:
initWithNibName:bundle:
You basically have two types of connections:
Outlet: This is how you teach one object about the existence of another object. For example, you might have a controller object that needs access to a button. You create an outlet (either in XCode Text Edit in the controller.h file/property area or in IB by adding an outlet) in your controller and then control-click-drag from the outlet to the button.
Actions: This is how you trigger an event on one object to call a method on another object. Actions will have a prototype of:
- (IBAction) someMethod:(id) sender;
I think the ":(id) sender" is optional if your method does not need a link to the object causing the event.
Within IB, you can arrange objects and set various attributes like size, color, position, target/actions, user interactions, Files Owner...
That brings me to files owner. Big concept here. It tends to be the Controller that loads the NIB (OK: I have a custom window controller I have used for over 15 years but Apple has a really good one UIViewController that does all sorts of goodness.) and acts as a proxy in IB. It is not actually instantiated in IB but it will be when you alloc and request it to load the NIB (XIB files are XML files that are turned into NIB files by the compile process)

Interface Builder. How do I Replace Programatic ViewControllers with IB ViewControllers?

As I move more and more of my UI construction from XCode to IB there is one remaining hurdle I need to clear.
Currently, I create my custom viewControllers in XCode with custom initializers. They typically have a bunch of ivars that are set during initialization via passed params. I would really like to move as much of this as I can to IB.
Could someone carefully explain to me - or, better, point me to code - how to replicate the XCode approach of passing params via custom initializer in IB - presumably via IBOutlet.
Thanks in advance.
Cheers,
Doug
UPDATE:
A typical scenerio is my AppDelegate will go out to the network, grab some data - NSMutableData, and then pass a reference to a root viewController - typically a TableViewController - that is pushed on the viewController stack of an navigationController.
When a cell is selected an secondViewController is alloc/init'ed and a subset of the data is passed to it. The secondViewController goes to the network for a bit more data, builds a view hierarchy, hands bits of the retrieved data to each subview and then each subview is messaged with setNeedsDisplay to process the data.
It is this hierarchical data passing that I want to hand off to IB is possible.
You can still have a custom initializer. However, inside this initialized you'll call -[initWithNibName:#"yourNibName" bundle:bundle]. You will connect your UIKit related instance variables (UILabel, UIButton, etc.) in Interface builder and therefore won't have to instantiate those objects in your initializer. Other instance variables (strings, dictionaries, custom objects, etc.) you'll instantiate and set in your initializer.
Also, keep in mind that manipulation of your UIKit related variables such as setting label text, or setting the position of a UIView, should be done in the viewDidLoad method since these objects may not have been fully created at the time initializer is executing.
Let me know if you need more information.
Lets say we have MyViewController which extends UIViewController and MyViewControllerParameter which is one of our custom objects we pass into MyViewController on initialization. MyViewController has an IBOutlets of type MyViewControllerParameter defined in it. We want to put MyViewController into another containing view, ParentView.xib. ParentView.xib is owned by ParentViewController.m and created elsewhere. We double click ParentView.xib in XCode to launch Interface Builder. We then drag an "object" from the Library View (I believe you open the library view with Cmd+Shift+L if its not open by default) onto the Document window. (This is the window activated by Cmd+0.)
An "Object" is an arbitrary widget found in the library (identified by a solid gold cube icon) that can represent anything in your project. After we've placed the new object into the document window, we type Cmd+4 to open the Indentity Inspector Window. In the top text field we can type the name of our view controller parameter, "MyViewControllerParameter". Next we find the ViewController widget in the library and drop it into the document window. We open the Attribute inspector (Cmd+1) and set the nib name to "MyView.xib". This should cause CocoaTouch to load MyViewController using the definitions in "MyView.xib".
Open the identity inspector and set the class attribute to MyViewController. Last we right click or control click (or two finger tap if we've correctly configured the trackpad on our MacbookPro) MyViewController in the document window. That will open a window showing all of the IBOutlets in MyViewController. Drag a line from the little open circle next to the MyViewControllerParameter outlet and drop it on the MyViewControllerParameter object sitting in the document window. Connecting these dots is how you set parameters between objects using interface builder.

Custom UIView built with Interface Builder accessible/positionable via Interface Builder

This shouldn't be this confusing. I have a custom UIView with a bunch on controls on it. UILabels, buttons, etc. I've created this Nib using Interface Builder. I want to be able to position this custom uiview on another UIView using the interface builder.
How do I link my UIView custom class, to the nib? initWithCoder gets called, but I want this class to get loaded from the nib.
Thanks
For this to work, you have to create a plug-in for Interface Builder that uses your custom control's class. As soon as you create and install your plug-in, you will be able to add by drag and drop, instances of your view onto another window or view in Interface Builder. To learn about creating IB Plugins, see the Interface Builder Plug-In Programming Guide and the chapter on creating your own IB Palette controls from Aaron Hillegass's book, Cocoa Programming for Mac OS X.
Here is the link to the original author of the accepted answer to a similar question.
You only need to make a plugin if you want the custom view to draw correctly in the nib you are using it. You can make a custom control and then have it show as a blank rectangle until instantiated during run right now.
How do I get a view in Interface Builder to load a custom view in another nib?
You can insert a UIViewController object using Interface Builder, and then set the UIViewController's "Nib name" property.
I don't know if this messes up your model, but I think it's the only way to do what you're trying to do.
In IB bring up the Identity Inspector tool (Command-4) then select your custom view and in the Class pop-up choose the name of your custom class instead of generic UIView. You may want to connect it to an ivar as well. In your ViewController declare an instance of your custom class with an IBOutlet in front of it. Then go back and bring up the Connections Inspector and connect your view to the ivar by click-dragging from the custom-view's referencing outlet to the File's Owner (which should be an instance of your ViewController) and choosing the ivar name.
When your NIB is loaded it should be creating an object of that type and connecting it to that variable.