More than one custom cell with in the same XIB - ios

Is it possible to have more than one custom uitableviewCell within the same xib?
I'm trying to save XIB files by combining different customized cells within the same xib and then having the Table load different ones from it.
In IB, I tried setting each of the uiTableViewCell class to a different custom class .m/.h implementation. Here is what I tried:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"DevConfigCell";
DeviceInfoCell *cell = (DeviceInfoCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if(cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"CustomTableViewCell~iphone" owner:self options:nil];
cell = ( DeviceInfoCell *)[nib objectAtIndex:0];
}
return cell;
}
In another table, i would reuse the nib, but i would do this:
cell = ( SecondDeviceInfoCell *)[nib objectAtIndex:0];
For some reason it always loads the first cell.
Should this all work? or is there a way?
Thanks

I'm trying to save XIB files by combining different customized cells
within the same xib
Why? There's no limit on the number of .xib files you can create.
and then having the Table load different ones from it.
When you load a .xib, all the objects that file contains are created. If you put 10 custom cells in one .xib, loading that .xib will create an instance of each of those 10 cells. That's probably not what you want. Keeping your cells in separate .xibs is probably a better plan.
cell = ( SecondDeviceInfoCell *)[nib objectAtIndex:0];
You seem to be confused about what casting does. When you cast from one type to another, you're not somehow selecting a different object. The object returned by [nib objectAtIndex:0] is always going to be the same if the nib array has the same contents. Casting just changes the type that the compiler associates with the value; in this case it changes the type of the pointer.
You can create an IBOutletCollection in your view controller and then connect several different custom cells to that outlet collection; that'll give you an array of cells that you can select from using objectAtIndex:. But again, that's really not a good idea since you'll be creating all the cells in the file every time you need just one.

NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"PlayerAvgsTableCell" owner:nil options:nil];
for(id currentObject in topLevelObjects)
{
if([currentObject isKindOfClass:[PlayerAvgsTableCell class]])
{
cell = (PlayerAvgsTableCell *)currentObject;
break;
}
}
}

Related

registerNib for a UITableViewCell in an XIB with multiple views

I've successfully been able to use registerNib to define a UITableViewCell's UI within an XIB that only has one UITableViewCell prototype within it.
In the interest of encapsulation, would it be possible to have an XIB with more than one UITableViewCell in it and still be able to load the proper cell using registerNib?
If so, how would one identify the desired cell prototype within the XIB in code?
I'm currently doing this in the tableView's VDL which works fine:
[self.tableView registerNib:[UINib nibWithNibName:#"LogoCell" bundle:[NSBundle mainBundle]]
forCellReuseIdentifier:CellId];
Is there a way to specify which cell prototype within the XIB we want to use?
Thanks in advance.
In the interest of encapsulation, would it be possible to have an XIB with more than one UITableViewCell in it and still be able to load the proper cell using registerNib?
No.
Actually, it is possible. If you have some way of distinguishing the views in your XIB (tags, custom classes, etc), then you don't even need to register the nib – all you have to do is this:
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSInteger cellIndex = 12345;
NSString *cellIdentifier = #"MyAwesomeCell";
// dequeue cell or, if it doesn't exist yet, create a new one from the nib
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (!cell)
{
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"MyNibWithLotsOfCustomCells" owner:self options:nil];
NSUInteger index = [topLevelObjects indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
// if you distinguish the views by class
return [obj isMemberOfClass:NSClassFromString(cellIdentifier)];
// if you distinguish the views by tag
return [(UIView*)obj tag] == cellIndex;
}];
cell = topLevelObjects[index];
}
// etc.
}
It's important to use dequeueReusableCellWithIdentifier: and not dequeueReusableVellWithIdentifier:forIndexPath: (the difference is explained in this thread).

how do you configure a tableviewcell in a tableview that is added to a UItableviewcontroller in a XIB?

I am using a tableview inside a uiviewcontroller inside a XIB. Because the controller is not a UItablecontroller, I cannot configure the cell directly. If I drag in a tableview cell, i can configure that with the cell identifier etc,but the XIB doesn't use my tableview cell. How do I join them up?.I would rather not use code as this seems counterintuitive to the workflow.
If you are using Storyboards you can directly add custom cells within the VC and configure them. But if you are using xib's you have to either create a custom cell class and load them programmatically or create a custom class with custom cell in separate xib and then load the custom cell from xib, or even you just create a xib with a simple custom table cell and load from xib. Refer apple Docs on UITableView
So as I understood, you want a custom cell in your code. If you are not using storyboards, try using this. Here I have created a custom class for custom cell and added the custom cell in xib. I added a separate xib, dragged and dropped UITableViewCell in xib(remove any views if present). Now click on the cell you just added, in the identity inspector change the class name to that of the custom class you created. Select files owner and change its class to the name of class where you need your custom cell. (This tells thats your cell will be used in that particular class where the tableview's delegate and datasource is connected).
Now in the class where you want your cell, add a IBOutlet of type UITableViewCell. Connect this to the cell you created in xib.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"CustomCell";
YourCustomCell *cell = (YourCustomCell*)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (!cell)
{
[[NSBundle mainBundle] loadNibNamed:#"YourCustomCell"
owner:self
options:nil];
cell = self.yourOutletCell;
self.yourOutletCell = nil;
}
}
And if you are using xib's to load and if you have more than one xib's of custom cell, you can load them via the xib name like this
NSArray *topLevelObjects;
topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"YourCustomCell" owner:self options:nil];
for (id currentObject in topLevelObjects)
{
if ([currentObject isKindOfClass:[UITableViewCell class]])
{
cell = (YourCustomCell *) currentObject;
break;
}
}
If it is a static Cells, you can point to this cell with Outlet and then return it in the cellForRowAtIndexPath

Custom table cell, custom XIB and long press recognizer - can't make them work together

I have a custom cell that has a button on it. I would like to experiment with using a long press instead.
The code that creates the cell looks like this:
CustomCell *cell = (CustomCell *)[aTableView dequeueReusableCellWithIdentifier:#"CustomCell"];
if (!cell)
{
cell = [[[NSBundle mainBundle] loadNibNamed:#"CustomCell" owner:self options:nil] lastObject];
}
(etc)
So I did this:
CustomCell *cell = (CustomCell *)[aTableView dequeueReusableCellWithIdentifier:#"CustomCell"];
if (!cell)
{
// cell = [[[NSBundle mainBundle] loadNibNamed:#"CustomCell" owner:self options:nil] lastObject];
cell = [[[NSBundle mainBundle] loadNibNamed:#"CustomCellDwellToSpeak" owner:self options:nil] lastObject];
}
Then I made a copy of the original xib. Deleted the button. Dropped an UILongPressGestureRecognizer on the cell, and created a target by control-dragging form the recognizer to the file's owner:
- (IBAction)longPress:(UILongPressGestureRecognizer *)sender;
However, once I start generating cells, I get this error:
TypOHD[41541:c07] -[UILongPressGestureRecognizer label]: unrecognized selector sent to instance 0x17d0be60
What's up with that?
I never got or found an answer to the question as such. What I did learn was that this plan is potentially flawed. Apparently mixing your won gesture recognizers in with the table view is a recipe for disaster, or at least heartbreak.
I my case, I decided to go with a fixed layout that consisted of just the number of items that would be shown anyway. In my app I was really only using a table for historical reasons anyway, and never needed to display more than 7 items.
A workaround and a hack, but it worked for me.

iOS 5 cellForRowAtIndexPath Memory Leak

I have been testing the application on the device (iOS 5) while using Instruments and I found a couple of memory leaks.
This is the part of the code I'm being redirected to from Instruments (see the arrow for exact line):
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
CeldaUltimasFotosViewCell *cell =
(CeldaUltimasFotosViewCell *) [self.tableView
dequeueReusableCellWithIdentifier:#"CeldaUltimasFotosViewCell"];
if (cell == nil) {
- - - - > NSArray *topLevelObjects =
[[NSBundle mainBundle]
loadNibNamed:#"CeldaUltimasFotosViewCell"
owner:nil options:nil];
cell = [topLevelObjects objectAtIndex:0];
}
// Configure the cell...
[[cell titulo] setFont:fuente_titulo];
...
return cell;
}
As you can see, I have a custom cell which is loaded from a NIB file. There are three files for the cell (customCell.m, customCell.h, customCell.xib). The thing is that I don't know if I have to release something in the cell controller (which is now empty, no methods), since this is iOS 5 with ARC.
check out my answer here:
How can I recycle UITableViewCell objects created from a XIB?
you don't even need to use loadNibNamed any more on iOS5
Take a look at the Table View Programming and how to load cells from NIB (XIB) files.
https://developer.apple.com/library/ios/#documentation/userexperience/conceptual/TableView_iPhone/TableViewCells/TableViewCells.html#//apple_ref/doc/uid/TP40007451-CH7-SW1
The first thing weird is that you are storing the cell in a local variable. You should be wiring the custom cell up to a property in the class and all you call in your code is:
[[NSBundle mainBundle] loadNibNamed:#"CeldaUltimasFotosViewCell" owner:self options:nil];
Follow the code from Loading Custom Table-View Cells From Nib Files and you can't go wrong.

Best way of loading custom cells from a XIB

I have an app, and I'd need custom UITableViewCells, I've been trying different ways, but no one works for what I want, or simply don't work. Can someone guide me how can I do it? Actually the cell, needs to have some UIImageViews and an UILabel and a UITextView. Thanks in advance!
Create a NIB file with a single UITableViewCell in it.
Loading the cell from the nib is a two liner:
NSArray* objects = [[NSBundle mainBundle] loadNibNamed:#"TheFile"
owner:nil
options:nil];
UITableViewCell* cell = [objects objectAtIndex:0];
This method will allways access disk when used, so it can be slow. On iOS 4 and later the is a better help class that caches the NIB in memory, for faster creation. Use like this:
// Cache this one!
UINib* nib = [UINib nibWithNibName:#"TheFile" bundle:nil];
// Then do:
NSArray* objects = [nib instantiateWithOwner:nil
options:nil];
UITableViewCell* cell = [objects objectAtIndex:0];

Resources