UITableView CustomCell crash on Button Click - iphone

This is very common question at SO though I have google and cross check my code few times but I am not able to figure out the crash
*** -[MyCustomCell performSelector:withObject:withObject:]: message sent to deallocated instance 0x96f6980
I have a CustomCell named MyCustomCell with XIB where I have 3 buttons for Facebook,Twitter,LinkedIn. I gave them all IBAction in CustomCell class.
When I click on any of them I get this kind of crash.
I am using ARC.
In my ViewController class I have cellForRowAtIndexPath
{
static NSString *CellIdentifier = #"MyCustomCell";
MyCustomCell *cell = (MyCustomCell*)[myTableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:CellIdentifier owner:self options:nil];
cell = (MyCustomCell *)[nib objectAtIndex:1];
}
return cell;
}
MyCustomCell.m
- (IBAction)facebookPressed:(BaseButton *)sender {
}
- (IBAction)twitterPressed:(BaseButton *)sender {
}
- (IBAction)linkedInPressed:(BaseButton *)sender {
}

I made this mistake just today! :) all you gotta do is replace the 2 lines
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"NameOfCustomCellNibFile" owner:self options:nil];
cell = [nib objectAtIndex:1];
You have to load the loadNibNamed: with the .xib file's name. I also thought it was with the identifier, but that is regarding the name that is referenced into the cell instead of the nib for the cell.
Hope this helps!

you can also code for Custom cell like this way. At nib of custom cell drag one UIButton and set it's tag in Xib. then use bellow Method:-
UIButton *btnMulSelected;
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *CellIdentifier =[NSString stringWithFormat:#"%d_%d",indexPath.section,indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
[[NSBundle mainBundle]loadNibNamed:#"cell_custome_iphones" owner:self options:nil];
cell = self.tblCell;
self.tblCell = nil;
btnMulSelected =(UIButton*)[cell.contentView viewWithTag:2];
[btnMulSelected addTarget:self action:#selector(MyButtonAction:) forControlEvents:UIControlEventTouchUpInside];
}
return cell;
}
Do not connect IBAction from Nib. just connect Custom-cell IBOutlate or put Unique UIButton tag from nib.

You've to keep the class name of cell and the XIB names same.
Keep the owner nil generally.
Also, if there is only 1 view ( i.e. 1 UITableViewCell in your case ), then this view is available at index 0 instead of index 1.
Inside the XIB file, make sure you link the button to your view itself, i.e. to IBOutlet or IBAction.
The linked buttons must be already added to your view, not floating outside in XIB. Otherwise they will instantiate and come at other indices of the loaded array. If you don't want a certain button for some time, then just keep it hidden.
So the code can be as below:
NSArray *views = [[NSBundle mainBundle] loadNibNamed:#"MyCustomCell" owner: nil options:nil];
MyCustomCell *cell = (MyCustomCell*)[views objectAtIndex:0];
Further make sure you do the following for creating XIB
Ok, then here goes the other portion simple process:
Create a MyCustomCell class derived from UITableViewCell class.
Create a separate .xib file with same name as MyCustomCell.xib.
Open .xib and delete the existing view in it. drag and drop a new
UITableViewCell from the objects of editor.
See the image to change the class name of the UITableViewCell in XIB to your class name.
Now the objectAtIndex 0 will return MyCustomCell.
Add all your buttons and other views in this UITableViewCell of your XIB.

Related

Custom Table Cell Loading Data Objective C iOS -

Currently I have the following method, but it doesn't quite work...
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *MyIdentifier = #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
[[NSBundle mainBundle] loadNibNamed:#"TVCell" owner:self options:nil];
cell = tvCell;
self.tvCell = nil;
}
UILabel *label;
label = (UILabel *)[cell viewWithTag:5];
label.text = [NSString stringWithFormat:#"Hole #%d", indexPath.row];
return cell;
}
The table view gets created with no errors, but each individual cell contains nothing, but clearly the TVCell.xib has a label with a tag of 5. The only question I have is this. I don't quite understand these steps apple gives here...
Select File’s Owner in the nib document window, open the Identity pane of the inspector, and set the class of File’s Owner to your custom view controller class.
Connect the cell outlet of File’s Owner (now the placeholder instance of your custom subclass) to the table-view cell object in the nib-file document.
Here is where those steps are...
http://developer.apple.com/library/ios/#documentation/UserExperience/Conceptual/TableView_iPhone/TableViewCells/TableViewCells.html#//apple_ref/doc/uid/TP40007451-CH7
Can someone please explain those steps for a noob like me? I think that is what I messed up on, but I could have done anything wrong.
I don't think TcCell becomes a property of self. Try this instead when the cell queue is empty:
if (cell == nil) {
cell=[[NSBundle mainBundle] loadNibNamed:#"TVCell" owner:self options:nil];
}
It's kind of difficult to explain the steps that you said you don't understand in words. I would suggest looking for tutorials that have images or videos for that. (I did a quick search and there are lots available, but I didn't really want to choose one to direct you to without having read them more closely).
However, I prefer to create custom table view cells this way:
http://www.mobilesce.com/2011/12/27/the-best-way-to-do-custom-reusable-uitableviewcells/
It's slightly different from the way described in the apple docs, but I've seen a lot of people use it and I find it easier.
The NSBundle method loadNibNamed:owner:options: returns an NSArray containing the top level objects in your nib file. Try this:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
NSArray *nibArray = [[NSBundle mainBundle] loadNibNamed:#"TVCell" owner:self options:nil];
cell = [nibArray objectAtIndex:0];
}

How can i create a custom UITableViewCell?

I want to know how can i create a custom UITableViewCell with three parts in the UITableViewCell like that:
Create a blank XIB with a UITableViewCell and design the cell dropping elements on it. Set arbitrary tags (1,2,3...) on each element so you can retrieve them later.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *identifier = #"xxx";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil) {
NSArray *nibObjects = [[NSBundle mainBundle] loadNibNamed:#"NameOfTheBlankXIB" owner:self options:nil];
cell = [nibObjects objectAtIndex:0];
}
// get the elements inside the cell by tag and set a value on them
UILabel*label = (UILabel*)[cell viewWithTag: 1];
label.text = #"some text";
return cell;
}
Another way is to go to the NIB and set this view controller as the file owner and hook the the cell to a ivar of the view controller, like IBOutlet UITableViewCell *tableViewCell.
Now loading this with this instance as the owner automatically hooks the cell to the outlet tableViewCell.
[[NSBundle mainBundle] loadNibNamed:#"NameOfTheBlankXIB" owner:self options:nil];
// at this point the cell is hooked to the ivar so you get a reference to it:
cell = self.tableViewCell;

Using multiple custom cells without reusing identifier

I feel like a real noob asking this, but here's my problem:
I want to show a tableView, with 7 custom cells. None of these cells is reused. That means the user will see 7 different cells, not more, not less.
I created the cells in the viewDidLoad method, and added all those cells in the listCells-array. After that, I used easy-mode to draw those cells:
UITableViewCell *cell = nil;
if (indexPath.row == 0)
{
static NSString *MyIdentifier = #"Cell";
cell = (DetAlertCell *)[localTableView dequeueReusableCellWithIdentifier:nil];
if (cell == nil) {
[[NSBundle mainBundle] loadNibNamed:#"DetAlertCell" owner:self options:nil];
cell = [listCells objectAtIndex:indexPath.row];
}
}
....
However, this won't work. It shows me a blank view. Every cell is created using a .xib-file and a .h and .m class. Is there anything that I'm missing and should do?
Just don't call the [localTableView dequeueReusableCellWithIdentifier:nil] and loa the correct cell for the index path.
Also you say that you load the cells in the viewDidLoad, then why do you load the nib:
[[NSBundle mainBundle] loadNibNamed:#"DetAlertCell" owner:self options:nil];
They should already be the array should they not.
And why to you check if the row is 0 then load the row, still will only load the first row.
Try this:
- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
return [listCells objectAtIndex:indexPath.row];
}

Custom UITableViewCell erroring

I am trying to build a custom table view using a cell that I built in IB. I am getting a strange error:
<BroadcastViewController 0x4b4f5f0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key postText.
Everything is wired up correctly in IB to the cell controller. Not really sure why this is happening.
This is what my cellForRowAtIndexPath looks like:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//Get the folder object of interest
Broadcast *messageAtIndex = [self.messages objectAtIndex:indexPath.row] ;
static NSString *CellIdentifier = #"BroadcastTableViewCell";
static NSString *CellNib = #"BroadcastTableViewCell";
BroadcastTableViewCell *cell = (BroadcastTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
//ERRORING ON THIS LINE...
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:CellNib owner:self options:nil];
cell = (BroadcastTableViewCell *)[nib objectAtIndex:0];
}
cell.postText.text = messageAtIndex.replyText;
cell.authorName.text = messageAtIndex.postCreatorFirstName;
cell.postDate.text = messageAtIndex.creationDate;
return cell;
}
Anyone seen this kind of error before? Let me know if you need any more information...
What is really strange is that it complains that the class BroadcastViewController is not KVC compliant to postText.
As far as I can see, postText is a label in your cell, so the IBOutlet for this should be in the BroadcastTableViewCell class. So check out where you've linked the postText label in IB. Also, it can be that you had an IBOutlet in your view controller for this label, you've removed it but you forgot to delete the link in IB. Anyway, there somewhere is your problem. The fact that you have the error on that line is just because it's there you load your NIB, it doesn't have anything to do with the cell itself or with the owner.
Might has something to do with dequeueReusableCellWithIdentifier returning an UITableViewCell*.
I normaly do this:
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier...
CustomCell* acell = (CustomCell*)cell;
Set the owner to nil.
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:CellNib owner:nil options:nil];
Ok figured it out. The connections in IB were indeed incorrect. I had them linked to the file's owner as opposed to the actual objects. I am going to give this too Stelian because he directed me to check out the nib. Thanks for all your help!

How to add a custom subview to a UITableViewCell derived class when the UITableViewCell is loaded using loadNIB

I am trying to add a custom view control to a custom UITableViewCell which I had designed in the interface builder.
Now, to load UITableCellView I am using
NSArray * loadedViews = [[NSBundle mainBundle] loadNibNamed:#"CustomSearchResultsCell" owner:self options:nil];
What method of the CustomSearchResultsCell class will be called the Nib loads the view and initializes it. I tried using viewDidLoad, but UITableViewCell does not respond to this method. Also initWithStyle is not being called in this case.
TIA
Nitin
Views loaded from a nib are initialized with initWithCoder:, which you can implement in a similar way like initWithFrame:.
Also, take a look at Apple' Sample Code called AdvancedTableViewCells. In this example they use following code to load table view cell from XIB:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"ApplicationCell";
ApplicationCell *cell = (ApplicationCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
[[NSBundle mainBundle] loadNibNamed:#"IndividualSubviewsBasedApplicationCell" owner:self options:nil];
cell = tmpCell;
self.tmpCell = nil;
}
return cell;
}