hey people im having trouble with loading my array of strings into a tableview , what i have already done is parse information and stored the data i need into an mutablearray of elements called statues1, now what i want to do is load up the statues1 into the table view with customize lable so the user can see all the values , now my problem is that when i load up the table view it gives an error ""BAD EXCESS", Please help me out for this?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
int counter=indexPath.row;
NSString *CellIdentifier = [NSString stringWithFormat:#"%d",counter];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
cell.selectionStyle=UITableViewCellSelectionStyleNone;
UIImageView *imgViewBack=[[UIImageView alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 100.0)];
imgViewBack.image=[UIImage imageNamed:#"black-_image.png"];
[cell.contentView addSubview:imgViewBack];
if(statuses1)
{
UILabel *lblTitle=[[UILabel alloc] initWithFrame:CGRectMake(100.0, 10.0, 200.0, 20.0)];
lblTitle.text=[statuses1 objectAtIndex:indexPath.row];
[cell.contentView addSubview:lblTitle];
[lblTitle release];
}
//[cell.contentView addSubview:btnRowButton];
}
return cell;
}
Instead of adding a new label view for each cell, you can
cell.detailTextLabel.text = [statuses1 objectAtIndex:indexPath.row];
I'm not sure, but that release after that could be causing the error. You just check out hte traceback to see if you can figure out which call caused it (the little yellow button with a bug on it)
Related
In a normal situation when working with a UITableView I have the standard code for reusing old cells:
- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"Cell";
UITableViewCell *cell = [tv dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
return cell;
}
I noticed, however, that in the case when I added subviews to the cell that they weren't deleted and that a new view were added every time. I have an example below that demonstrate it perfectly:
- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"Cell";
UITableViewCell *cell = [tv dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil)
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
UILabel *label = [[UILabel alloc] init];
label.text = #"HELLO";
label.frame = CGRectMake(arc4random() % 50, -1, 286, 45);
label.backgroundColor = [UIColor clearColor];
// Add views
[cell addSubview:label];
return cell;
}
I need some code that reuses my labels again in the same way the cells are being reused. What should I do?
Thanks
You must only add the subviews if you are making a new cell. If you are dequeuing, the subview is already present and should not be re-created.
Your method should be:
- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"Cell";
UITableViewCell *cell = [tv dequeueReusableCellWithIdentifier:cellIdentifier];
UILabel *label;
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
label = [[UILabel alloc] init];
label.tag = 1;
// Add views
[cell addSubview:label];
}
else
{
// Label will already exist, get a pointer to it
label = [cell viewWithTag:1];
}
// Now set properties on the subview that are unique to each cell
label.text = #"HELLO";
label.frame = CGRectMake(arc4random() % 50, -1, 286, 45);
label.backgroundColor = [UIColor clearColor];
return cell;
}
Note how the label is only created when the cell is nil. Otherwise, it is found using the tag.
I need some code that reuses my labels again in the same way the cells
are being reused.
No, you need to understand the table view design better. It should be obvious why the views are being added multiple times – reusing a cell means that you take a previous instance of UITableViewCell that’s no longer needed (thus saving a costly allocation of a new object) and reuse this instance for the new cell. But this previous instance already has the label attached to it, so the number of labels grows.
I would subclass UITableViewCell and put the label creation inside the initialization code for this new class. (Or create a UIView subclass and set it as the cell’s contentView, as suggested in this nice table tutorial by Matt Gallagher.) That’s the proper way to encapsulate the view details and hide them from the table data source.
you can use something like in the else part for if(cell == nil)
for (UIView *sub in [cell.contentView subviews])
{
if([UILabel class] == [sub class])
NSLog(#"%#",[sub class]);
UILabel *label = (UILabel *)sub;
//do label coding ie set text etc.
}
I use lazy initialization of views within my custom table cell class.
It only needs to load views and "addSubview" once.
- (void) lazyInitTitleLabel {
if (_titleLabel != nil) {
return;
}
_titleLabel = [[UILabel alloc] initWithFrame: CGRectMake(10.0f, 10.0f, 200.0f, 30.0f)];
// Cell adds the label as a subview...
[self addSubview: _titleLabel];
}
The only thing you need to be careful about is resetting any content that views display like text in your labels and images in your image views. If you don't old content may get reused along with the recycled table cells.
Good luck!
I am using UITableView in my application and I have created custom cell in the file DealsCC.xib and when cell is tapped the color of the cell should be changed to blue but it does not happen in my code. I write the code as follows:
static NSString *MyIdentifier = #"dealsCC";
dealsCC *cell = (dealsCC *)[tableView dequeueReusableCellWithIdentifier:MyIdentifier];
[cell selectionStyle:UITableViewCellSelectionStyleBlue];
I want to mention that in the line
[cell selectionStyle:UITableViewCellSelectionStyleBlue];
warning msg exists and it is "dealsCC may not respond to -selectionStyle"
plz help me to solve this problem
thanx in advance.
please see the following stackoverflow links,please check whether you have followed correclty them
1)link1
2)link2
3)enter link description here
Try this in your custom class for the table view cell
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
self.selectionStyle = UITableViewCellSelectionStyleBlue;
[super setSelected:selected animated:animated];
}
The warning is because the method should be
[cell setSelectionStyle:UITableViewCellSelectionStyleBlue];
and not [cell selectionStyle:UITableViewCellSelectionStyleBlue];
Use cell.selectionStyle = UITableViewCellSelectionStyleGray; for changing the style of the cell selection. But here the selectionStyle only takes input of UITableViewCellSelectionStyle type.
For changing Color you need to use Image. Use selectedBackgroundView.image property and Follow the tutorial Link
Or you can also try
cell.selectedBackgroundView = [[[UIView alloc] initWithFrame:CGRectZero] autorelease];
cell.selectedBackgroundView.backgroundColor = [UIColor redColor];
EDIT:
OK I am updating code in case you have any other controls on the cell, then you can try below code.
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"myCellId";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
UIView *v = [[[UIView alloc] init] autorelease];
v.backgroundColor = [UIColor redColor]; // any color of your choice.
cell.selectedBackgroundView = v;
// After this line add all other controlls you are adding...
}
// Set up the cell...
cell.textLabel.text = #"foo";
return cell;
}
I have a UITableView with 1000 elements. Before loading it for the first time Instruments shows 2.20MB of bytes still alive. After charging it shows 4.82MB. When I release the memory and return to the previous state it shows 4.71MB. But now when I load the same table, Instruments shows 4.82MB again. Is the structure of the UITableView stored in the cache? If yes, is there any way to release this memory?
My table construction:
(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *MyIdentifier = #"SearchResult";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier] autorelease];
}
if(!isSomeStateSearching) cell.textLabel.text = [[[contentSomeState objectAtIndex:indexPath.section] objectForKey:#"rowValues"] objectAtIndex:indexPath.row];
else
{
cell.textLabel.text = [searchedAllContent objectAtIndex:indexPath.row];
}
UIView *v = [[[UIView alloc] init] autorelease];
v.backgroundColor = [UIColor colorWithRed:188/255.0 green:57/255.0 blue:25/255.0 alpha:1.0];
cell.selectedBackgroundView = v;
UIImageView *arrow = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"seta_navegacao"]] autorelease];
cell.accessoryView = arrow;
return cell;
}
Of course you use the reuse mechanism of your UITableViewCell correctly, right?
You should be allocating and adding cell subviews only when initialising a new cell. As it stands you are creating a new view and image view every time a cell is reused. This is why your table is taking up so much memory.
Hey guys i have a table view that can add and delete cells. but when i delete the only cell that comes with the app, and i try to add a new cell with the text of "Meghan Way" and the text just automatically changes it self to the original cells text which is "House 1" here is my code!
- (IBAction)saveButton:(id)sender {
FacePlatesViewController * viewController = (FacePlatesViewController
*)self.parentViewController;
[viewController addObject:[NSMutableDictionary dictionaryWithObject:text.text
forKey:#"name"]];
[self dismissModalViewControllerAnimated:YES];
}
- (IBAction)cancel:(id)sender {
[self dismissModalViewControllerAnimated:YES];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:
(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero
reuseIdentifier:CellIdentifier] autorelease];
cell.textLabel.text = [[cells objectAtIndex:indexPath.row] valueForKey:#"name"];
UIImage * myimage = [UIImage imageNamed: #"check.png"];
image = [[UIImageView alloc]initWithImage:myimage];
tableView.backgroundColor = [UIColor clearColor];
self.myTableView = tableView;
}
return cell;
}
this is for the save button! any help would be very appreciated:D Thanks
You code is quite messed up. I have improved it below and added comments:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:
(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero
reuseIdentifier:CellIdentifier] autorelease];
} //The if block should end here. You should set the cell's label irrespective whether the cell was nil. This is the cause of the issue you are facing.
cell.textLabel.text = [[cells objectAtIndex:indexPath.row] valueForKey:#"name"];
//You are doing nothing with the UIImage
//UIImage * myimage = [UIImage imageNamed: #"check.png"];
//image = [[UIImageView alloc]initWithImage:myimage];
//You should be setting the background color just once, in ViewDidLoad, not here.
//tableView.backgroundColor = [UIColor clearColor];
//I don't see why this is required
//self.myTableView = tableView;
return cell;
}
Are you storing the text labels for these cells in any kind of array or dictionary and loading them in there using the standard "cellForRowAtIndexPath?" If so, then you need to delete the dictionary / array entry in that data source to prevent it from being used again.
I can't tell for sure without seeing some more code...but it sounds like a cell recycling issue. I could be wrong...but I'd need to see more info.
I am having a problem setting a UIImageView or UIView on the cell of the Grouped table on the iPhone.
For this I am using this code
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *SimpleTableIdentifier = #"SimpleTableIdentifier";
NSArray *listData =[self.tableContents objectForKey:[self.sotreKeys objectAtIndex:[indexPath section]]];
UITableViewCell * cell = [tableView
dequeueReusableCellWithIdentifier:SimpleTableIdentifier];
if(cell == nil) {
cell = [[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:SimpleTableIdentifier] autorelease];
}
if(indexPath.section == 1 && indexPath.row ==1)
{
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(240, 14, 40, 40)];
imageView.image = [UIImage imageNamed:[NSString stringWithFormat:#"Back.png",nil]];
[cell.contentView addSubview:imageView];
[imageView release];
}
NSUInteger row = [indexPath row];
cell.textLabel.text = [listData objectAtIndex:row];
return cell;
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
But it is not placed on the cell . When ever I select the row it will display for that time only, what is the problem?
Does anyone have any idea what the problem is. I think the image is getting overwritten by the cell .
Thanks in advance
try making
cell.accessoryType = UITableViewCellAccessoryNone;
It seems that you are adding image on accessory view.
If yes, you can add cell.accessoryView = imageView;
I do have some ideas of what might be happening.
You are adding an image view to the contentView then you are setting the text of the textLabel which is a part of the contentView and is probably sitting on top of the image. Try this and see if you can at least see your image on the left side.
cell.imageView.image = [UIImage imageNamed:#"Back.png"];
Now when you dequeue cells you need to remember that all the views you added last time you created the cell are still there, so as you scroll you will just be stacking back buttons on top of each other.
Also the following line [tableView deselectRowAtIndexPath:indexPath animated:YES]; is dead code because it occurs after a return statement. You might want to place that in the delegate call – tableView:willDisplayCell:forRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *SimpleTableIdentifier = #"SimpleTableIdentifier";
NSArray *listData =[self.tableContents objectForKey:[self.sotreKeys objectAtIndex:[indexPath section]]];
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:SimpleTableIdentifier];
if(cell == nil) {
cell = [[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:SimpleTableIdentifier] autorelease];
}
if(indexPath.section == 1 && indexPath.row ==1)
{
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(240, 14, 40, 40)];
imageView.image = [UIImage imageNamed:#"Back.png"];
[cell.contentView addSubview:imageView];
[imageView release];
}
cell.textLabel.text = [listData objectAtIndex:indexPath.row];
return cell;
}
Make sure that your image is named "Back.png" not "back.png" because the iOS on the phone is key sensitive.