I have two class and in both class tableview uses custom nib file(for table cell)as well as i make IBOutlet instance of myview controller to that custom cell nib file but i can not use same nib for both class becuase i have give file owner of that xib to the myviewcontroller so when i used that one in another class it give error so any ideas so use the same xib for both the view controller?
If you want to reuse your custom table cell with multiple view controllers, check out this answer. The two methods described there let you load your custom table cell from a nib file without having to set the File's Owner to your specific controller.
Related
How to re-use .xib file as a template to another .xib file within one application.
I want one xib which will be like a template (for example xib with logo)
and I will import it like a subview on another xib file.
How can I do it?
Define a new view in the xib that you want to import, and create a class file:
#interface MyView : UIView
Set MyView as the class of your xib view, in the object inspector.
From the other xib, place an empty view, then change its class to MyView
I would like to change at run time the custom class as defined in a xib identity inspector.
This is to avoid to define lots of xib and view controller.
I've not found anything related to that subject.
Define a MyCustomUIViewController that would inherit from UIViewController. And set that controller as the file's owner of your XIB. This controller will have to support the defualt XIB IBOutlet and IBActions.
Then make other controllers (MyCustomUIViewControllerForThis, MyCustomUIViewControllerForThat, ...) inherit from MyCustomUIViewController
Then when you load it, that should give something like :
MyCustomUIViewControllerForThat* controller = [[MyCustomUIViewControllerForThat] alloc] initWithNibName:#"YourNib" bundle:nil];
This way, you can define in your XIB wanted Outlets and actions, and customize them if wanted in your MyCustomUIViewControllerForThat class.
In most sample and generated examples, the structure of XIBs for UIViewController subclasses is:
Placeholders
File's Owner = Class of UIViewController subclass
First Responder
Objects
View (wired to view outlet of owner)
However this structure does not allow for previewing of layout: File's Owner does not support the attributes inspector to display "simulated metrics". In order use the attributes inspector for the view controller, the following XIB structure is necessary:
Placeholders
File's Owner = Class of UIViewController subclass
First Responder
Objects
A UIViewController
View (wired to view outlet of owner)
My question is: is there any reason not to do this? The containing UIViewController seems to be ignored when the XIB is loaded, so it seems to just do the job of a container for purposes of prototyping and previewing in the IB.
However this structure does not allow for previewing of layout: File's Owner does not support the attributes inspector to display "simulated metrics".
Any root UIView instance does.
I'm having trouble creating a UIView (in Interface Builder) that contains a UITableView with some other object, such as a UIButton or UILabel. The UITableView always takes up the maximum amount of space in the UIView, regardless of the size of the UITableView object itself. The File Owner is a standard UITableViewController.
Here's how to do this easily:
1) Create a table view controller with xib.
2) Change the inherited type in the .h file from UITableViewController, to UIViewController.
3) Add the protocols UITableViewDataSource, UITableViewDelegate to the .h file.
4) Open the xib, add in a view.
5) drag the table view in the xib under the view, resize as desired.
6) Wire the "view" property of the File's Owner to the View instead of the UITableView. The datasource and delegate properties of the table view should still be wired to File's Owner.
7) (optional) if you want to be able to reload or otherwise access the table outside of table view controller delegate methods that pass in a table view, make a UITableView * IBOutlet named "myTable" or the like, and wire the table in IB to that.
An alternate approach is to make a new UIViewController with xib, add a table to the xib, wire datasource/delegate to the file's owner, and make a new UITableViewController class which you use to copy the methods from into your view controller, then delete.
Unfortunately, creating a UITableView in Interface Builder (IB) is was very problematic for me. I ran into the same problems as you as a beginning developer and, after much frustration, just ended up abandoning IB for UITableViews.
The best solution for me was to just implement the UITableViewController (and the UINavigationController that you use as a header) programmatically. Once you figure out the whole Model-View-Controller paradigm, it is actually fairly straightforward.
Some good resources for dealing with them programmatically can be found in Apple's documentation with these names:
"Table View Programming Guide for iPhone OS"
"View Controller Programming Guide for iPhone OS"
Cocoa with love has an article about Recreating UITableViewController to increase code reuse. This is useful if you can't use a UITableViewController, but want to make sure that your UIViewController will behave the same way.
I was trying to follow the Table View Programming Guide for iPhone OS but was having trouble creating a new Table View Controller that loads its data from a nib file.
Specifically, I was trying to follow the steps in this part:
If you prefer to load the table view
managed by a custom table-view
controller from a nib file, you must
do the following:
In Interface Builder, create an empty Cocoa Touch nib file (File >
New).
Drag a UITableViewController object from the Interface Builder
Library into the nib document window.
Save the nib file in your project directory under an appropriate name
and, when prompted, select your
project to have the nib file added to
it.
Select Table View Controller in the nib document window and open the
Identity pane of the inspector. Set
the class to your custom table-view
controller class.
Select File’s Owner in the nib document window and set its class
identity to the custom table-view
controller class.
Customize the table view in Interface Builder.
Select the table-view controller in the nib document window, open the
Attributes pane of the inspector, and
enter (or select) the name of the nib
file in the Nib Name field.
So I created a new UITableViewController subclass in Xcode (called "MyTableViewController"), then I went into IB and followed those steps. I made sure to link up all the Class attributes to the same name as the UITableViewController subclass I made in Xcode like it says in the steps.
But now I get the following warning in IB:
"My Table View Controller" has both its
"View" and "Nib Name" properties set.
This configuration is not supported.
When I run the application and push the table view controller, it appears but it seems like nothing is being loaded from the nib file at all (e.g. I set the alpha to 0 instead of 1).
Any idea as to what I'm doing wrong?
Thanks for the help.
Here's some more information that might help you understand the situation better.
I noticed a few differences between creating a UITableViewController with the template (e.g. by creating a new Navigation-based Application) vs. creating one yourself (e.g. following the steps above). I'm going to refer to each as TemplateNib and CustomNib, respectively, to make it easier to understand the differences.
In TemplateNib, it has the following objects in the document window:
File's Owner
First Responder
Table View
In CustomNib, it has the following objects in the document window:
File's Owner
First Responder
My Custom Table View Controller
Table View
Another difference is in the File's Owner links...
TemplateNib's File's Owner:
Outlets
tableView -> Table View
view -> Table View
Referencing Outlets
dataSource -> Table View
delegate -> Table View
CustomNib File's Owner:
Outlets
view -> (nothing)
CustomNib My Table View Controller:
Outlets
view -> Table View (this is grayed out so you can't delete it)
Referencing Outlets
dataSource -> Table View
delegate -> Table View
Update:
I tried to mimic the .xib file that is created by the template by following these steps:
Created an empty file in Interface Builder.
Set the File's Owner to the class that inherits from UITableViewController.
Added a Table View to the document window.
Set the Table View's dataSource and delegate to File's Owner.
Set the File's Owner view to the Table View.
Added a tableView propery in the Identity pane of type UITableView.
Set the File's Owner tableView property (which I just created) to the Table View.
However, this still seems like it is not loading it from the NIB file. (I also never set the name of the NIB file anywhere though... is there anyplace I need to set it or does it look for one with the same name?).
I then tried overriding initWithNibName to load from the name of the nib file, and now it does seem to load it from the nib file. However, if I look at the .m file of the TemplateNib table view controller, it doesn't need to override this method, why is that? I still think I am doing it the wrong way cause the Programming Guide didn't mention anything about doing it this way.
Update:
I tried comparing the two .xib files using a diff tool, the only significant difference between the two seems to be:
<string key="superclassName">UITableViewController</string>
// and:
<reference key="NSSuperview"/>
I don't see any reference to the Nib file in the original file anywhere, are there any other files I should check?
Update:
It seems like the thing that makes TemplateNib load from the nib file is that in the MainWindow.xib (default name given by the template), the RootViewController is added with the NIB Name property having the value "RootViewController". Additionally, its class is set to "RootViewController".
I tried putting a breakpoint in both initWithNibName:bundle: and initWithStyle: on the RootViewController, however, it never gets to there. I'm kinda wondering how the TableViewController is created when you set it up in the MainWindow.xib like that.
I also tried adding the my custom table view controller to MainWindow.xib, setting the class and nib names in hopes that it will load it from the nib file I specified, but it doesn't even call iniWithNibName.
Create a TableViewController in Xcode.
Create an empty nib file in Interface Builder.
Set the File's Owner Class property to the TableViewController from step 1.
Add a TableView to the empty nib file.
Set the File's Owner view property to the TableView from step 4.
Customize the TableView in IB as you want.
Override the initWithNibName:bundle: method in Xcode for the TableViewController you created and use code similar to the following:
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
if (self = [super initWithNibName:#"MyNibName" bundle:nibBundleOrNil]) {
// Custom initialization
}
return self;
}
I had this same problem last night and found this post while trying to search for the answer. I ended up solving it.
Basically I had opened up the wrong XIB file (I hoped main_window.xib, not the view controllers xib)
I cut all the controls from my main xib, pasted them into the controllers xib, realigned everything, reconnected all the outlets/actions and the warning went away :)
Hope this helps someone :)
Instead of doing all that, I would use the "New File" iPhone UI template to create a TableViewController with xib file option checked. Then you get a controller and xib file all wired together properly.
Eagle, when you create a new file, select the "UIViewController subclass" icon. There's a checkbox to make it a UITableViewController subclass just above the checkbox to include XIB file.
You've got two places where your UITableViewController shows up in Interface Builder.
(1) It shows up in the nib with the controllers own name.
(2) It shows up as a controller object in the nib of another object, usually the MainWindow.
Your problem is at (2). There are two ways to set the tableview for a UITableViewController in Interface builder. First, you can create a UITableView under the controller in the MainWindow and connect that to the controller's view property. Secondly, you can bring up the inspector in the attributes pane and in the popmenu listed "NibName" select the name of the controllers nib.
You can't use both systems at once because the first loads a view from the MainWindow nib file and second loads a completely unrelated view from the controller's separate nib file.
This is one of those maddening errors that using Interface Builder makes so hard to track down.