I have a custom UITableViewCell loaded from a nib file. Everything works fine until I scroll down past the last cell such that the table view has to bounce back when I let go.
Then, the cells towards the top of the list are blank and remain blank until I manually refresh the table view.
Image of issue: [iPhone Screenshot][1]
Here is my cell for row code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"TimeEntryCellIdentifier";
TimeEntryCell *cell = (TimeEntryCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"TimeEntryCell" owner:self options:nil];
for (id oneObject in nib) {
if ([oneObject isKindOfClass:[TimeEntryCell class]]) {
cell = (TimeEntryCell *) oneObject;
}
}
}
TimeEntry *aTimeEntry = [appDelegate.timeEntries objectAtIndex:indexPath.row];
cell.clientName.text = aTimeEntry.ClientName;
cell.category.text = aTimeEntry.CategoryName;
cell.hours.text = [NSString stringWithFormat:#"%#", aTimeEntry.Hours];
[TimeEntry release];
return cell;
}
Any ideas?
[1]: http://dl.nvthost.com.s3.amazonaws.com/Screen shot 2011-02-18 at 2.46.42 PM.png
[1]: http://dl.nvthost.com.s3.amazonaws.com/Screen shot 2011-02-18 at 2.46.42 PM.png
I don't think you should be doing the
[TimeEntry release];
there on the next to last line. You didn't allocate it in that method, just pulled a reference from the delegate. The retain count is probably zero at that point. When iOS starts releasing memory that TimeEntry will be dealloc'd.
The problem turned out the be the view hierarchy in IB. Even though I put a view in the cell and then dragged UILabels onto the view, they ended up on the same level as the view. After I moved the UILabels under the view it appears to be working.
Related
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.
I have a UITableViewController with an attached xib file. Inside the xib file i have a TableViewCell object with a view inside it along with labels on the view. Below is an image of what my result should be:
pic1 http://casperslynge.dk/2.png
And below is how my tableview is looking atm.
pic2 http://casperslynge.dk/iphone1.png
My issue is that I can't get the table view cell to fill the entire window. Have tried everything inside the interface builder. Nothing to do with the origin or the width/height. Below is how I instantiate my cell with the xib file and fill my labels with data.
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString * CompanyListCellIdentifier =
#"CompanyList";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CompanyListCellIdentifier];
if (cell == nil) {
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"CompanySubscriptionView" owner:self options:nil];
cell = [topLevelObjects objectAtIndex:0];
}
NSUInteger row = [indexPath row];
CompanyModel *company = [list objectAtIndex:row];
name.text = company.name;
network.text = company.networks;
NSString* subscriptionCountString = [NSString stringWithFormat:#"%d", company.subscriptions.count];
subscriptionCount.text = subscriptionCountString;
fromPrice.text = company.fromPrice;
NSString* trustScoreString = [NSString stringWithFormat:#"%d", company.trustScore];
trustScore.text = trustScoreString;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
The weird thing is that in the next view when one of the cell's are pressed, I have no issue making the view fill the entire width and height, and it is created in exactly the same way (see picture below). Is it something in the xib file that I am doing wrong or in the code?
pic3 http://casperslynge.dk/iphone2.png
Can anybody help?
As I see from screenshots you are trying to use table view with grouped style while you definitely need a plain one (at least for first view).
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];
}
i have set up a tableview with custom cells. customCell is a class.
heres the code for a more accurate view:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSManagedObject *object = (NSManagedObject *)[entityArray objectAtIndex:indexPath.row];
NSString *cellIdentifier = [NSString stringWithFormat:#"asd%d", indexPath.row];
customCell *cell = [[tableView dequeueReusableCellWithIdentifier:cellIdentifier] autorelease];
//i tried setting a tag but dunno how to call it afterwards
[cell setTag:indexPath.row];
if (cell == nil) {
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"customCell" owner:self options:nil];
cell = [topLevelObjects objectAtIndex:0];
}
if (cell.imagen != nil) {
[[cell imageView] setImage:[cell imagen]];
} else { /* setup image... */ }
}
-(void) webImageReady:(WebImage *)downloadedImage imageView:(UIImageView *)imageView cellTag:(NSInteger *)cTag
{
// This is the part where i want to access cell.imagen, this is actually wrong...
[[[imageView.superview viewWithTag:cTag] imagen] setImagen:downloadedImage.Image];
[imageView setImage:downloadedImage.Image];
}
Ok. now i want to access (reference) the cell.imagen property from a method outside cellForRowAtIndexPath, more precisely at a selector for a download finished (delegated)
Thanks in advance!
Do it inside cellForRowAtIndexPath if the image is downloaded, and on successful download of the image do [tableview setNeedsDisplay]
You shouldn't refer to the cell outside the cell creation method, you should consider the case the cell was rendered but while getting the image was scrolled out the dealloced or even reused for another cell, one way to solve it is to have image view array or something similar.
I think you should try using a third party lib that already doing it(among other things) called Three20. It have an object call TTImageView that gets a URL and loads it in the background, it solves all of the cases along with optimized caching
What I've done is created a custom TableCell view that gets populated with information from an array of objects. Each TableCell gets loaded in the
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"CellIdentifier";
Cell *cell = (Cell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"Cell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
NSUInteger row = [indexPath row];
NSDictionary *rowData = (NSDictionary *)[self.surveys objectAtIndex:row];
cell.info1.text = [rowData objectForKey:#"info1"];
cell.info2.text = [rowData objectForKey:#"info2"];
cell.info3.text = [rowData objectForKey:#"info3"];
cell.otherInfo = [rowData objectForKey:#"otherInfo"];
return cell;
}
In addition to this I specify a custom height for the cell here
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 76.0;
}
When the value for tableView: heightForRowAtIndexPath: is 76 it loads all the cells that I can see and they aren't ever blank. Without changing anything else in the code I can modify the value in tableView: heightForRowAtIndexPath: and it will only show the first cell value when the view is loaded. As I scroll down they are refreshed with a value as soon as their top edge hits the top of the screen. When I get back up to the top and stretch the view so that it bounces back the bottom ones will disappear.
As far as I can tell, the change in height somehow affects how they are loaded but I can't for the life of me see how.
I specified a height in the custom cell .xib that was different than the one I was specifying in code. Once this was changed to match the size specified in the code the problem went away.
Another thing to pay attention to isn't just the size of the Custom table view cell's height but also the height of other sub views as well.
I had this problem when one of my UIImageView objects was higher than the cell height it would cause this very same problem.
Thanks for the post as it helped me sort out my issue too. +1 (wont let me vote up or I would, sorry)