Using custom controls with Interface Builder - iphone

I have a custom ViewController which allows selection of an image from a grid. The ViewController uses the AQGrid control and is really just a modified version of the samples shipped with AQGrid.
I'm trying to hook it up in InterfaceBuilder, but documentation on how to do this seems sparse. In standard Cocoa apparently I should create an IB plugin to use with IB, but I'm just looking for the quickest option really as there are a few of these custom ViewControllers which I need to hook up (including a rating control). I've also tried dragging the "Object" controller in IB to my tabpage, but it just gets added to the tree outside of the tabcontroller (see screenshot).

As far as I understand your question, you have to add a generic UIViewController to your nib file and then change its class in the Identity inspector to whatever you need as long as it's a subclass of UIViewController.

Use a "Custom View" object and assign the appropriate class in the inspector's info tab. Using Interface Builder plugins isn't really advisable anymore, because Xcode 4 doesn't support them.

Related

what does IB do behind the scene when I link IBoutlets/IBActions?

I am new to mac dev, xcode and IB etc. I understand how to build simple applications and basic dragging & dropping in IB, but i don't know what and where does IB do with the objects.
the second questions is how to write a MVC without using IB?
When you connect two objects in IB with IBOutlet or IBAction it creates some special tags in XIB (which is XML).
When bundle (update: sorry, it's not a bundle, but UINib) reads NIB (which is compiled XIB) it looks for such tags and objects they are refer. After that:
For outlets it uses KVC (Key-Value Coding) to set corresponding property of receiving object.
For actions it calls addTarget:action:forControlEvents: on control object.
You can build iPhone app of any complexity without IB by creating and setting up objects in your code, but in most cases it's just not wise.
Further reading - Resource Programming Guide
As far as I know, the XIB files from IB are some kind of archives with your objects and their properties stored in them. When you send -initWithNibName, the objects are unarchived. So basically, you could - if you knew how - create your own XIB files and they should work. Note that loading a UIViewController without specifying a XIB file, an XIB file with the same name as your class is loaded. See the Wikipedia article.
To your second question: You can create any object you add using IB programmatically. Typically, these are UIView subclasses that you initialize using initWithFrame:. Then you set the properties you need. Finally, you add them to your view using addSubview.
IBActions are basically Target/Action Pairs. If you for instance add UIBarButtonItem, you use initWithBarButtonSystemItem:target:action:. Setting the action is equal to setting an IBAction connection in IB.
You should be able to create any User Interface you want programmatically, however it's usually a lot of work compared to when using IB.

Custom UIView from Interface Builder

I'm trying to keep things organized and create hierarchy of views for my app.
So for instance I want to create a custom view to display some text, another custom view to display progress and then use all those views in the main view created with View-Based Application template.
I know how to create it programmatically - you create UIView subclass, implement drawRect method, place an empty UIView in Interface Builder and chance it's Class to my custom class. My problem is that I want to create those custom view's in Interface Builder instead programmatically.
So far I've created UIViewController controller with XIB file and in viewDidLoad method of view controller from the template I create that custom view controller instance and add it's view as a subview of that empty UIView added in Interface Builder (the same you would change Class in programmatic approach).
It works, but it's more of a hack for me and it's hard for me to believe that there isn't a better method where I could add those custom views in interface builder without having to implement viewDidLoad method and create controllers and add their views inside of that method.
This was originally a comment in Ratinho's thread, but grew too large.
Although my own experience concurs with everything mentioned here and above, there are some things that might ease your pain, or at least make things feel a little less hack-ish.
Derive all of your custom UIView classes from a common class, say EmbeddableView. Wrap all of the initWithCoder logic in this base class, using the Class identity (or an overloadable method) to determine the NIB to initialize from. This is still a hack, but your at least formalizing the interface rules and hiding the machinery.
Additionally, you could further enhance your Interface Builder experience by using "micro controller" classes that pair with your custom views to handle their delegate/action methods and bridge the gap with the main UIViewController through it's own delegation protocol. All of this can be wired together using connectors within Interface Builder.
The underlying UIViewController only needs to implement enough functionality to satisfy the "micro controller" delegation pattern.
You already have the details for adding the custom views by changing the class name and handling the nib loading. The "micro controllers" (if used) can just be NSObject derived classes added to the NIB as suggested here.
Although I've done all of these steps in isolated cases, I've never taken it all the way to this sort of formal solution, but with some planning it should be fairly reliable and robust.
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.
Maybe i didnt understand u?
you have library in the Interface builder u can move every component u want and place it on your view. (u can add another view by adding UIView and change its class name in the 4th tab).
then u declare vars with IBOutlet and connect them from the 2nd tab of ur file's owners to their components...another question?
Unfortunately, you can't do what you want to do with UIKit. IB Plugins only work for OS X, and Apple explicitly doesn't allow them for use with iOS development. Something to do with them not being static libraries. Who knows, they may change this someday, but I wouldn't hold your breath.

iPhone - Creating custom objects for Interface Builder?

I am currently subclassing UIView to create custom objects, they work perfectly fine
In interface builder i drag and drop a uiview and I set the class name to my custom view, and in runtime the view will populate according to my code.
QUESTION: Is it possible to make it so that my custom view DRAWS in interface builder, And maybe drag and drop my custom view ?
I've researched this myself a while back, as far as i know this is not possible using the iPhone SDK.
When developing for the Mac SDK you can create your own IB plugins.
You need to add the custom view to the Interface Builder library. Go to File -> Read Class Files... in interface builder, and select your header file to add your item to interface builder's list.

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)

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.