I created a prototype cell in storyboard with four labels
then in my code i am adding different background images for first,last and other rows.
for first row all 4 labels are hidden.
Intially all 5 rows shown in screen appear good.but when i scroll up to see 6th row ,it behaves like first row and all 4 labels are hidden.
here is my code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
Employee *currentEmployee=[Employee sharedData];
NSArray *tempArray =currentEmployee.leaveApproveDict;
static NSString *simpleTableIdentifier = #"approveLeaveCell";
approveLeaveCell *cell = [self.approveLeaveView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[approveLeaveCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
if([tempArray count]!=0){
if(indexPath.row == 0){
UIImageView *imgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"h_t_top_bar.png"]];
cell.backgroundView = imgView;
cell.fromLabel.hidden=YES;
cell.toLabel.hidden=YES;
cell.typeLabel.hidden=YES;
cell.nameLabel.hidden=YES;
[cell setUserInteractionEnabled:NO];
}
else{
if(indexPath.row ==[tempArray count]){
UIImageView *imgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"h_t_bottom_bar.png"]];
cell.backgroundView = imgView;
}
else{
UIImageView *imgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"h_t_repeat_bar.png"]];
cell.backgroundView = imgView;
}
//assign the data
if(indexPath.row-1 < [tempArray count]){
NSDictionary *tempLeave= [currentEmployee.leaveApproveDict objectAtIndex:indexPath.row-1];
cell.toDateLabel.text=[self extractLeaveDate:(NSString*) [tempLeave objectForKey:#"leaveTo"]];
cell.fromDateLabel.text=[self extractLeaveDate:(NSString*)[tempLeave objectForKey:#"leaveFrom"]];
cell.leaveLabel.text=[tempLeave objectForKey:#"leaveType"];
cell.employeeNameLabel.text=[tempLeave objectForKey:#"requesterName"];
}
}
return cell;
}
The same issue happens with me. I have solved it using two different customized UITableViewCell and two identifiers.
A UITableView object maintains a queue (or list) of the currently reusable cells, each with its own reuse identifier, and makes them available to the delegate in the dequeueReusableCellWithIdentifier: method.
Did you use ARC in your project? If you did not use arc, then cell should use autorelease:
cell = [[[approveLeaveCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier] autorelease];
/* Remove all existing content from list and reload them again to avoid
* overlay of cell content */
for(UIView *view in cell.contentView.subviews){
if ([view isKindOfClass:[UIView class]]) {
[view removeFromSuperview];
}
}
// VKJ
Related
I am loading custom separator image in uitableview cell.
Here is my code :
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath: (NSIndexPath *)indexPath
{
static NSString *CellID=#"Cell"
MyTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:SwitchCellIdentifier];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
UIImageview *aSwitch = [[UIImageview alloc] initWithImage:[UIImage imageNamed:#"divider.png"]];
separator.frame = CGRectMake(0,50,320,1);
[cell.contentView addSubview:seperator];
}
if(cell.height == 22)
{
/// here i am setting frame for uiimageview
}
but i am getting seperator image disappears for only one row out of 20 while scrolling.
Can you please help why it is loading like this.
If you've put your separator UIImage out of the bounds of the cell, and set cell.clipsToBounds = NO; to have the separator image displayed, the separator image might get hidden by drawing the next cell.
You can't control the z-index of the cells as they're being drawn on screen, it depends from where you're scrolling (bottom to top, or top to bottom).
If that's indeed you're issue, you can either put the divider inside the cell's frame, or if your separator is thin enough use:
[TableView setSeparatorColor:[UIColor colorWithPatternImage:[UIImage imageNamed:...]]];
self.tblView=[[UITableView alloc] initWithFrame:CGRectMake(0,0,320,370) //set as u need
style:UITableViewStylePlain];
self.tblView.delegate=self;
self.tblView.dataSource=self;
[self.view addSubview:self.tblView];
UIView *v = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 10)];//set as u ne
v.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"divider.png"]];
[self.tblView setTableHeaderView:v];
[self.tblView setTableFooterView:v];
[v release];
I have UITableView with Custom View on it.
For the bottom of the tableview, I add a "Load More" cell there.
After clicked, the tableview load more data successfully and the "Load More" cell still at the bottom of the tableview.
However, after I clicked the first "Load More", the second "Load More" appears, and the custom view still exist in the same cell of second "Load More". "Load More" and custom view are on the same cell. I want that cell only appear "Load More".
This problem exists for the third, fourth "Load More".
Can anyone help me?
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return imageCurPos+1;
}
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if([aTableView tag]==501){
// Main Table
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:CellIdentifier];
[[cell viewWithTag:3007] removeFromSuperview];
const NSInteger BOTTOM_LABEL_TAG = 3002;
UIImageView *bottomLabel;
UILabel *loadMore;
if(indexPath.row < imageCurPos){
if (cell == nil)
{ //All repeat things come here, if don't want to repeat here, please state outside this brucket
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
//Edited
for (UIView *view in [cell.contentView subviews])
{
[view removeFromSuperview];
}
bottomLabel = [[[UIImageView alloc] initWithFrame: CGRectMake(50, 30, 250, 112)] autorelease];
[cell.contentView addSubview:bottomLabel];
bottomLabel.tag = BOTTOM_LABEL_TAG;
cell.backgroundView =
[[[UIImageView alloc] init] autorelease];
cell.selectedBackgroundView =
[[[UIImageView alloc] init] autorelease];
UIImageView *iconView = [[[UIImageView alloc] initWithFrame:CGRectMake(0, 30, 45, 45)] autorelease];
iconView.image = [UIImage imageNamed:#"02_bubble.png"];
[[cell contentView] addSubview:iconView];
bottomLabel.image = [UIImage imageNamed:#"05_bubble.png"];
}else if(indexPath.row == imageCurPos ){ //For Load More
if (cell == nil)
{ //All repeat things come here, if don't want to repeat here, please state outside this brucket
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
//Edited
for (UIView *view in [cell.contentView subviews])
{
[view removeFromSuperview];
}
loadMore =
[[[UILabel alloc]
initWithFrame:
CGRectMake( 0, 0, 300, 50)]
autorelease];
loadMore.text = #"Load more...";
loadMore.textAlignment = UITextAlignmentCenter;
loadMore.tag = 3007;
loadMore.textColor = [UIColor whiteColor];
loadMore.backgroundColor = [UIColor darkTextColor];
[cell.contentView addSubview:loadMore];
}
return cell;
}
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *) indexPath{
if([tableView tag]==501){
if([indexPath row] != imageCurPos){
}else{ // For load more
NSLog(#"noRow Prev: %d", imageCurPos);
imageCurPos += interval;
NSLog(#"noRow After: %d", imageCurPos);
[tbl_mo_main reloadData];
}
}
I think you should use 2 different identifiers, one for the normal cell and one for load more cell.
And one thing is that creating custom cell should be done in the block.
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
// create the views in side the cell and add it
...
}
Then outside this block, update the cell.
You can set the tag for your views in the creation of cell, and update the corresponding view by getting it with [cell.contentView viewWithTag:tag]
You may refer to this topic: Reload TableViewCell's UILabels in dynamic table
[cell.contentView addSubview:loadMore];
This line adds the label to cell contentview but when the cell is reused ..that label is still present in that cell.
Add the following code after if(cell == nil) in both if and else for index path checking.
for (UIView *view in [cell.contentView subviews])
{
[view removeFromSuperview];
}
I used the following code:
- (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];
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
if (indexPath.row == 0) {
CGRect myImageRect = CGRectMake(120.0f, 5.0f, 70.0f, 55.0f);
UIImageView *myImage = [[UIImageView alloc] initWithFrame:myImageRect];
[myImage setImage:[UIImage imageNamed:#"logo.png"]];
[cell.contentView addSubview:myImage];
}
else {
int arrayIndex = [indexPath row]-1 ;
mdict = [mmenuitems objectAtIndex:arrayIndex];
[mdict retain];
cell.textLabel.text =[mdict objectForKey:#"name"];
I got correct JSON parsed message in mmenuitems,and used indexPath.row = 0 to display a logo.
But the problem is I didn't get the last item in tableview.
Also when I scrolls the tableview the data reloads randomly and same gets repeated.
I can gusse that you need to add 1 to your number of rows method:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [mmenuitems count]+1//add 1 for the logo cell
}
So your rows count will be all the objects in the mmenuitems array + 1 cell for the logo.
But
a better way will be to add your logo to the table view header view and not to the table view rows, you can do it in your view did load after the table view is loaded:
CGRect myImageRect = CGRectMake(120.0f, 5.0f, 70.0f, 55.0f);
UIImageView *myImage = [[UIImageView alloc] initWithFrame:myImageRect];
[myImage setImage:[UIImage imageNamed:#"logo.png"]];
[self.tableView.tableHeaderView addSubview:myImage];
It will add your logo to a view on top of the first table row and won't mix in your table rows. I believe it will resolve your repetition problem.
Good luck
You could add + 1 to your numberOfRowsInSection method.
You can try using different identifiers for cells. Because the cell is being reused your contents are over written. It is not the good approach but it solves the problem nevertheless.
First of all you need to reset your cell everytime to avoid stale data
if (cell == nil) {
// cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
cell.textLabel.text = nil; //This clears any stale label
for(UIImageView *view in cell.contentView.subviews)
{
[view removeFromSuperView]; // This clears any subview added
}
Secondly,
Your number of rows should be
[mmenuitems count] + 1
I believe currently it is just [mmenuitems count]
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.
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.