iPhone/iPad : table view scroll crash in ipad - iphone

Hi all I want to show more than 120 images in tableview its runs fine in simulator but crash in device (ipad).
logs show memory warning but I am releasing perfectly I don't know why I get this message and crash. Images comes from server I am using following code.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
FullTableViewCell *cell = (FullTableViewCell *)
[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *topLevelObjects = [[NSBundle mainBundle]
loadNibNamed:#"FullTableViewCell" owner:nil options:nil];
for (id currentObject in topLevelObjects) {
if ([currentObject isKindOfClass:[UITableViewCell class]]) {
cell = (FullTableViewCell *)currentObject;
break;
}
}
}
NSDictionary *dic = [socketConnection().imageInfoArray objectAtIndex:indexPath.row];
int imageId = [[dic objectForKey:#"id"] intValue];
UIImage *image = [socketConnection().serverImageArray objectAtIndex:indexPath.row];
UIImage *IMMage = [self scaleImage:image toResolution:740];
cell.cellIMage.image = IMMage;
cell.addButton.tag = imageId;
cell.zoomOutButton.tag = imageId;
[cell.zoomOutButton addTarget:self action:#selector(_ZoomOut:) forControlEvents:UIControlEventTouchUpInside];
[cell.addButton addTarget:self action:#selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
cell.transform = CGAffineTransformMakeRotation(3.14159265+(3.14159265/2));
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
plz anybody help me where i am wrong..

Implement:
if (cell) {
[cell setImage:nil];
[cell setImage://image];
// Put ALL cell code here
}
and release:
image and IMMage and FullTableView and topLevelObjects and dic before
return cell;
AND FINALLY AND MOST IMPORTANTLY:
also analyze you're project to see for leaks

Related

custom label value is disappearing when scrolling table view

I am new to iphone. my cutomcell label value is disappearing when I scroll the table view.
Again it appears when I click on that cell.
Can anyone help me?
Thanks in Advance.
//table view in view controller created in xib
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"ListOfProductsCell";
ListOfProductsCell *cell = (ListOfProductsCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell==nil) {
NSArray *nib =[[NSBundle mainBundle] loadNibNamed:#"ListOfProductsCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
productItemDit=[productListArry objectAtIndex:indexPath.row];
NSString *offerStr= [NSString stringWithFormat:#"%.2f",[[productItemDit objectForKey:#"offer"] floatValue]];
NSString *fullCostStr=[[currencyCodeStr stringByAppendingString:#" "] stringByAppendingString:offerStr];
NSLog(#"%#",fullCostStr);
cell.itemCostLbl.text=fullCostStr;
} else {
cell.itemStepper = (UIStepper *) [cell viewWithTag:2];
cell.itemAddedLbl =(UILabel*)[cell viewWithTag:1];
}
if (tableView == self.searchDisplayProduct.searchResultsTableView) {
searchProductItemDit=[searchProductListArry objectAtIndex:indexPath.row];
NSLog(#"searchdit:%#",searchProductItemDit);
cell.itemNameLbl.text= [searchProductItemDit objectForKey:#"name"];
self.searchDisplayProduct.searchResultsTableView.separatorColor=[UIColor colorWithRed:200.0 green:0.0 blue:0.0 alpha:1.0];
} else {
productItemDit=[productListArry objectAtIndex:indexPath.row];
NSLog(#"dit:%#",productItemDit);
cell.itemNameLbl.text=[productItemDit objectForKey:#"name"];
}
cell.itemAddedLbl.text = [[NSString alloc] initWithFormat:#"%d",itemCount];
cell.itemImg.image = [UIImage imageNamed:#"profp.jpg"];
return cell;
}
Solved by doing like this
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"ListOfProductsCell";
ListOfProductsCell *cell = (ListOfProductsCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell==nil) {
NSArray *nib =[[NSBundle mainBundle] loadNibNamed:#"ListOfProductsCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
} else {
cell.itemStepper = (UIStepper *) [cell viewWithTag:2];
cell.itemAddedLbl =(UILabel*)[cell viewWithTag:1];
}
if (tableView == self.searchDisplayProduct.searchResultsTableView) {
cell.itemNameLbl.text= [[searchProductListArry objectAtIndex:indexPath.row] objectForKey:#"name"];
} else {
cell.itemNameLbl.text=[[productListArry objectAtIndex:indexPath.row] objectForKey:#"name"];
}
cell.itemCostLbl.text=[NSString stringWithFormat:#"%# %.2f", currencyCodeStr , [[[productListArry objectAtIndex:indexPath.row] objectForKey:#"offer"] floatValue]];
cell.itemAddedLbl.text = [[NSString alloc] initWithFormat:#"%d",itemCount];
cell.itemImg.image = [UIImage imageNamed:#"profp.jpg"];
return cell;
}
As you haven't post much of the information this is my guess.when you scroll table view it internally calls the reloadData method . You need to use reuse Identifier to preserve the state of the cell. You can initialize the cell in cellForRowAtIndexPath like :
static NSString *cellIdentifier = #"cellID";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
// or cell initializing logic here for the custom cell
}
in case of custom cell add reuse identifier in the xib and use it in your cellForRowAtIndexPath method

Checkmarks single selection

I'm currently developing a UITableView with items for selection with check marks.
The problem is I need to put a restriction on how many items are selected at a single time.
For Example:
NO onions, NO salt, YES milk, NO oranges.
As this example shows, I need a restriction so that the user can only select one item.
Current Code:
-(void)checkButtonPressed:(id)sender event:(id)event {
NSSet *touches = [event allTouches];
UITouch *touch = [touches anyObject];
CGPoint currentTouchPosition = [touch locationInView:self.myTableView];
indexP = [self.myTableView indexPathForRowAtPoint: currentTouchPosition];
NSMutableDictionary *item = [[NSMutableDictionary alloc] init];
//MasterCell *cell = [self.tableView dequeueReusableCellWithIdentifier:#"MasterCell"];
item = [arrayData objectAtIndex:indexP.row];
if (indexP != nil) {
[self tableView: self.myTableView accessoryButtonTappedForRowWithIndexPath:indexP];
}
[self.myTableView reloadData];
}
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath {
NSMutableDictionary *item = [arrayData objectAtIndex:indexPath.row];
BOOL checked = [[item objectForKey:#"checked"] boolValue];
[item setObject:[NSNumber numberWithBool:!checked] forKey:#"checked"];
UITableViewCell *cell = [item objectForKey:#"cell"];
UIButton *button = (UIButton *)cell.accessoryView;
UIImage *newImage = (checked) ? [UIImage imageNamed:#"unchecked.png"] : [UIImage imageNamed:#"checked.png"];
[button setBackgroundImage:newImage forState:UIControlStateNormal];
NSLog(#"accessoryButtonTappedForRowWithIndexPath____");
}
My cellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
NSMutableDictionary *item = [arrayData objectAtIndex:indexPath.row];
UILabel *nomeLabel = (UILabel *)[cell viewWithTag:2];
UIButton *btnCheck = (UIButton *)[cell viewWithTag:3];
BOOL checked = [[item objectForKey:#"checked"] boolValue];
UIImage *image = (checked) ? [UIImage imageNamed:#"checked.png"] : [UIImage imageNamed:#"unchecked.png"];
[btnCheck setBackgroundImage:image forState:UIControlStateNormal];
nomeLabel.text = [item valueForKey:#"nome"];
nomeLabel.textColor = [UIColor blackColor];
[btnCheck addTarget:self action:#selector(checkButtonPressed:event:) forControlEvents:UIControlEventTouchUpInside];
return cell;
}
Thanks in advance and sorry for my bad English, please don't down vote, just ask if you have any doubt I'm always around to answer.
Try this ::
.h File,
#property(nonatomic, retain) NSIndexPath *lastIndexPath;
.m File,
int oldRow, newRow;
Table Methods:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CustomCellIdentifier = #"customCell";
customCell *cell = (customCell *)[tableView dequeueReusableCellWithIdentifier: CustomCellIdentifier];
if (cell == nil)
{
NSArray *nib;
nib= [[NSBundle mainBundle] loadNibNamed:#"customCell" owner:self options:nil];
for (id oneObject in nib)
if ([oneObject isKindOfClass:[customCell class]])
cell = (customCell *)oneObject;
newRow = [indexPath row];
oldRow = [[self lastIndexPath] row];
cell.accessibilityViewIsModal = (newRow == oldRow && lastIndexPath != nil) ? NO : YES;
if(cell.accessibilityViewIsModal == NO)
cell.imgCheck.image = [UIImage imageNamed:#"Checkbox_Checked_New.png"];
else
cell.imgCheck.image = [UIImage imageNamed:#"Checkbox_Unchecked_New.png"];
return cell;
}
}
DidSelect ::
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
newRow = [indexPath row];
oldRow = [[self lastIndexPath] row];
//Check Mark Feature
if (newRow != oldRow)
{
customCell *newCell = (customCell *)[tableView cellForRowAtIndexPath:indexPath];
newCell.imgCheck.image = [UIImage imageNamed:#"Checkbox_Checked_New.png"];
customCell *oldCell = (customCell *)[tableView cellForRowAtIndexPath:lastIndexPath];
oldCell.imgCheck.image = [UIImage imageNamed:#"Checkbox_Unchecked_New.png"];
[self setLastIndexPath:indexPath];
}
else
{
customCell *newCell = (customCell *)[tableView cellForRowAtIndexPath:indexPath];
newCell.imgCheck.image = [UIImage imageNamed:#"Checkbox_Checked_New.png"];
[self setLastIndexPath:indexPath];
}
}
Basically, for this kind of business logic, you're going to have to code it yourself. When using table views as what are basically radio buttons, the only way to enforce the requirement of single selection is to write code that handles the situation of the user trying to select the second item in the manner that your system will require:
Allow multiple selections (not the case here, but in some cases you might)
Remove all other checks that are incompatible with this, check the selected item, and tell the table view to refresh all of the rows you just changed
Present an error to the user in some fashion (blink, alert, sound) – almost never a good idea when you can allow direct manipulation.
try like this may be it helps you, here lastIndexPath is an NSIndexPath variable declared in .h file.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell* Cell = [tableView cellForRowAtIndexPath:indexPath];
int new = [indexPath row];
int old = (lastIndexPath != nil) ? [lastIndexPath row] : -1;
if(new != old)
{
Cell.accessoryType = UITableViewCellAccessoryCheckmark;
UITableViewCell* oldCell = [tableView cellForRowAtIndexPath:lastIndexPath];
oldCell.accessoryType = UITableViewCellAccessoryNone;
lastIndexPath = indexPath;
}
}

Can not able to Select Cell from tableView

Hi friends it is a Strange Issue I'm facing, I am using Multiple UItableCustomCells in one Grouped TableView with Section's.
I am able to Select first Section's rows only, then when I click on another Section's row it's selection method is not working, I can not understand where is mistake, my cellForRowAtIndexPath code is Below:-
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *CellIdentifier =[NSString stringWithFormat:#"%d",indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
//if (cell == nil) {
if(indexPath.section==0)
{
if(indexPath.row==0)
{
[[NSBundle mainBundle]loadNibNamed:#"CustomCell1" owner:self options:nil];
cell = self.Cell1;
self.Cell1 = nil;
txtincidentName = (UITextField*)[cell.contentView viewWithTag:1];
}
else if(indexPath.row==1)
{
[[NSBundle mainBundle]loadNibNamed:#"CustomCell2" owner:self options:nil];
cell = self.Cell2;
self.Cell2 = nil;
lblDatefirst = (UILabel*)[cell.contentView viewWithTag:2];
btnCalfirst = (UIButton*)[cell.contentView viewWithTag:3];
lblTimeFirst = (UILabel*)[cell.contentView viewWithTag:4];
}
else if(indexPath.row==2)
{
[[NSBundle mainBundle]loadNibNamed:#"CustomCell2" owner:self options:nil];
cell = self.Cell2;
self.Cell2 = nil;
lblDatefirst = (UILabel*)[cell.contentView viewWithTag:2];
btnCalfirst = (UIButton*)[cell.contentView viewWithTag:3];
lblTimeFirst = (UILabel*)[cell.contentView viewWithTag:4];
lblInciTime =(UILabel*)[cell.contentView viewWithTag:9];
lblInciTime.text=#"Date/Time";
}
}
else if(indexPath.section==1)
{
if(indexPath.row==0)
{
[[NSBundle mainBundle]loadNibNamed:#"CustomCell3" owner:self options:nil];
cell = self.Cell3;
self.Cell3 = nil;
btndropDown1 = (UIButton*)[cell.contentView viewWithTag:5];
btndropDown2 = (UIButton*)[cell.contentView viewWithTag:6];
btndropDown3 = (UIButton*)[cell.contentView viewWithTag:7];
}
else if(indexPath.row==1)
{
[[NSBundle mainBundle]loadNibNamed:#"CustomCell4" owner:self options:nil];
cell = self.Cell4;
self.Cell4 = nil;
txtViewofdetails = (UITextView*)[cell.contentView viewWithTag:7];
}
}
return cell;
}
simulator image
Please Help and guide Thank you..
Don't load the cells from nibs like this. Instead register the cells with a reuse identifier in the NIB. This will cause the dequeueing pick the correct cell protoype based on the identifier.
Most likely your current approach messes up the touch handling of the table view.
hey try this type of concept and flow of the code
NSString *CellIdentifier =[NSString stringWithFormat:#"%d%d",indexPath.section,indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"CustomCell1" owner:self options:nil];
for (id currentObject in topLevelObjects){
if ([currentObject isKindOfClass:[UITableViewCell class]]){
cell = (CustomCell1 *) currentObject;
break;
}
}
}

Custom UITableViewCell with dynamic content

I'm trying to create a UITableView which loads a custom cell from a XIB. I have EventsCell.xib along with the .m and .h files.
The cell's content and height are dynamic, as it can contain an unknown number of subviews.
This is the code that loads the cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"EventsCellIdentifier";
EventsCell *cell = (EventsCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"EventsCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
NSDictionary *hour = [[[eventsArray objectAtIndex:[indexPath section]] valueForKey:#"hours"] objectAtIndex:[indexPath row]];
NSArray *events = [hour valueForKey:#"events"];
cell.events = events;
cell.timeLabel.text = [hour valueForKey:#"name"];
int offset = 0;
for(NSDictionary *event in events)
{
UIView *vvv = [[UIView alloc] initWithFrame:CGRectMake(50, offset, 270, 44)];
[vvv setBackgroundColor:[UIColor clearColor]];
UILabel *lab = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 200, 44)];
lab.text = [event valueForKey:#"name"];
lab.backgroundColor = [UIColor clearColor];
[vvv addSubview:lab];
[cell.contentView addSubview:vvv];
offset += 44;
}
return cell;
}
It loads the cells, but after i scroll a few times on the table view, the content looks like this:
What am i doing wrong?..
Thank you!
==================== UPDATE ====================
Now another thing is happening.
I've added all of the elements of the subviews i add to the cell in a separate view controller. Like bellow.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"EventsCellIdentifier";
EventsCell *cell = (EventsCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"EventsCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
for (UIView *subV in [cell.contentView subviews]){
[subV removeFromSuperview];
}
NSDictionary *hour = [[[eventsArray objectAtIndex:[indexPath section]] valueForKey:#"hours"] objectAtIndex:[indexPath row]];
NSArray *events = [hour valueForKey:#"events"];
cell.events = events;
cell.timeLabel.text = [hour valueForKey:#"name"];
int offset = 0;
for(NSDictionary *event in events)
{
EventBoxViewController *ebvc = [[EventBoxViewController alloc] initWithNibName:#"EventBoxViewController" bundle:nil];
ebvc.nameLabel.text = [event valueForKey:#"name"];
[ebvc.view setFrame:CGRectMake(50, offset, 270, 44)];
[cell.contentView addSubview:ebvc.view];
offset += 44;
}
return cell;
}
And they don't load as they should. Please see the image below.
They load only when i scroll through the cells and even then they don't load as they should.
Also the text for the label does not get assigned.
Any ideas on what i am doing wrong?
Thank you.
Views are added on cell.contentView, Since the cells are reuable it still remains added,
If we remove all the subViews it will work
for (UIView *subV in [cell.contentView subviews]){
[subV removeFromSuperview];
}
Add the above code after
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"EventsCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
It works if you add a UIVIew* to your table cell prototype and clear it's sub-views.
like this:
UIView* editView = (UIView*)[cell viewWithTag:102];
for (UIView *subV in [editView subviews]){
[subV removeFromSuperview];
More readable solution is instead of dequeueing a cell, to create one every time, but it depends how many of them you need to load in the end because of overhead. This removing thing looks nasty.

heightForRowAtIndexPath crashes

I have the following code:
- (CGFloat)tableView:(UITableView *) tableView heightForRowAtIndexPath:(NSIndexPath *) indexPath{
TestCell* cell = (ConvoreCell *) [tableView cellForRowAtIndexPath:indexPath];
CGSize textSize = [[cell text] sizeWithFont:[UIFont systemFontOfSize:14] constrainedToSize:CGSizeMake([tableView frame].size.width - 20, 500)];
return 80;
}
It crashes on the cellForRowAtIndexPath, why is this? The log doesn't tell me anything. Here's my cellForRowAtIndexPath method:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"ConvoreCell";
AsyncImageView *asyncImageView = nil;
TestCell * cell = (TestCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"TestCell" owner:nil options:nil];
for (id currentObject in topLevelObjects){
if ([currentObject isKindOfClass:[UITableViewCell class]]){
cell = (ConvoreCell *) currentObject;
break;
}
}
asyncImageView = [[[AsyncImageView alloc] init] autorelease];
asyncImageView.imageview = cell.icon;
}
else {
asyncImageView = (AsyncImageView *) [cell.contentView viewWithTag:ASYNC_IMAGE_TAG];
}
NSMutableDictionary *cellValue = [results objectAtIndex:indexPath.row];
NSString *picURL = [[cellValue objectForKey:#"user"] objectForKey:#"img"];
if ([picURL isEqualToString:#"https://secure.gravatar.com/avatar/1f043010eb1652b3fab3678167dc0487/?default=https%3A%2F%2Fconvore.com%2Fmedia%2Fimages%2Feric.png&s=80"])
picURL = #"https://test.com/media/images/eric.png";
[asyncImageView loadImageFromURL:[NSURL URLWithString:picURL]];
cell.title.text = [cellValue objectForKey:#"message"];
cell.info.text = [NSString stringWithFormat:#"%# %# days ago", [[cellValue objectForKey:#"user"] objectForKey:#"username"], [cellValue objectForKey:#"date_created"] ];
return cell;
}
All I want to do is to resize the height of the cell according to the cell.title.text....
It's wrong to call cellForRowAtIndexPath: manually. You have to store those strings separately in array and obtain them from there.
A rule of thumb: don't call framework callbacks manually.