I have a UITableViewCell. I can add and subtract 1 from the cell's textLabel and I can also delete the cells. Here is my problem, Lets say i add 5 to the value of the textLabel. And this cell is at the 0 indexPath (The First cell in the table). When I delete this cell and there are now no longer any cells on the table, I add a new cell and this new cell automatically gets the same value as the cell that was just deleted. SO this new cell will have a value of 5 and i want the cell to have a value of 1 just like every cell should when it is added. This only happens when a cell is deleted and a new cell is added at that exact same indexPath. So my question is: do i have to delete this cells "memory" or "data" for this to be fixed? Thanks a bunch for the help!
CellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
addBtn = [[UIButton alloc]init];
addBtn =[UIButton buttonWithType:UIButtonTypeRoundedRect];
[addBtn setFrame:CGRectMake(220,10,25,55)];
[addBtn addTarget:self action:#selector(addLabelText:) forControlEvents:UIControlEventTouchUpInside];
[addBtn setTitle:#"+" forState:UIControlStateNormal];
[addBtn setEnabled:YES];
[cell addSubview:addBtn];
subBtn = [[UIButton alloc]init];
subBtn=[UIButton buttonWithType:UIButtonTypeRoundedRect];
[subBtn setFrame:CGRectMake(260,10,25,55)];
[subBtn addTarget:self action:#selector(subtractLabelText:) forControlEvents:UIControlEventTouchUpInside];
[subBtn setTitle:#"-" forState:UIControlStateNormal];
[subBtn setEnabled:YES];
[cell addSubview:subBtn];
//cell.textLabel.text = #"1";
}
//cellText.hidden=!self.editing;
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
cell.imageView.image = [imageArray objectAtIndex:indexPath.row];
cell.textLabel.text = [number objectAtIndex:indexPath.row];
return cell;
}
When cells are deleted or go off screen, the table view saves them and reuses them later. So you need to reset textLabel's value in tableView:cellForRowAtIndexPath:. The UITableViewCell class reference says this:
The table view's delegate in tableView:cellForRowAtIndexPath: should always reset all content when reusing a cell.
Related
hi i am implementing a table in which i am getting request i have list of students to which i want to add as my room mate i have two button accept and reject the problem is here when i click on accept button i want that row will be deleted from the array and also i want to shift the deleted row value into the table of nextview controller in case of accept request . and in case of reject button cliked only want to delete the row not to move the value of cell into next view controller i am implementing this project by using storyboard can anybody have idea about that plase share me this is the code for cellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"DefaultCell"];
if(cell == nil) {
cell =[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:#"DefaultCell"];
}
acceptreq = [UIButton buttonWithType:UIButtonTypeRoundedRect];
acceptreq.frame =CGRectMake(170, 10, 60, 30);
rejectreq = [UIButton buttonWithType:UIButtonTypeRoundedRect];
rejectreq.frame =CGRectMake(240, 10, 60, 30);
[acceptreq setTitle:#"Accept" forState:UIControlStateNormal];
[rejectreq setTitle:#"Reject" forState:UIControlStateNormal];
[acceptreq addTarget:self action:#selector(Acceptrequest:) forControlEvents:UIControlEventTouchUpInside];
[rejectreq addTarget:self action:#selector(Rejectrequest:) forControlEvents:UIControlEventTouchUpInside];
[cell addSubview:acceptreq];
[cell addSubview:rejectreq];
[acceptreq setTag:indexPath.row];
cell.textLabel.text = [myarray objectAtIndex:indexPath.row];
return cell;
}
In short you can delete selected Row with clicking UIbutton like bellow:-
-(IBAction)Acceptrequest:(id)sender
{
UIButton *btn =(UIButton*)sender;
[myarray removeObjectsAtIndexes:btn.tag];
[tableView deleteRowsAtIndexPaths:myarray withRowAnimation:UITableViewRowAnimationAutomatic];
[tableVIew reloadData];
}
You need to implement this method:
[tableView deleteRowsAtIndexPaths:arrayOfIndexPathsToDelete withRowAnimation:UITableViewRowAnimationAutomatic];
I have a UITableView and i programatically add two buttons to the cell. 1 button adds to the cells text ( counts up ) the other subtracts 1 (counts down). However, lets say i add 4, the cell's text will be 4, but when i scroll that cell up and out of the view, when it comes back down into view, the cells text is back to 1 which is where it started out. The same happens if i add(it does the same if i subtract also) to the cells text and switch pages and then go back to the table view. Here is the cellForRow:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
newBtn = [[UIButton alloc]init];
newBtn=[UIButton buttonWithType:UIButtonTypeRoundedRect];
[newBtn setFrame:CGRectMake(260,20,55,35)];
[newBtn addTarget:self action:#selector(subtractLabelText:) forControlEvents:UIControlEventTouchUpInside];
[newBtn setTitle:#"-" forState:UIControlStateNormal];
[newBtn setEnabled:YES];
[cell addSubview:newBtn];
subBtn = [[UIButton alloc]init];
subBtn=[UIButton buttonWithType:UIButtonTypeRoundedRect];
[subBtn setFrame:CGRectMake(200,20,55,35)];
[subBtn addTarget:self action:#selector(addLabelText:) forControlEvents:UIControlEventTouchUpInside];
[subBtn setTitle:#"+" forState:UIControlStateNormal];
[subBtn setEnabled:YES];
[cell addSubview:subBtn];
}
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
cell.imageView.image = [imageArray objectAtIndex:indexPath.row];
cell.textLabel.text = [cells objectAtIndex:indexPath.row];
return cell;
}
Any and all help is appreciated! Thanks:D
Methods for buttons
- (IBAction)addLabelText:(id)sender{
cell = (UITableViewCell*)[sender superview];
cell.textLabel.text = [NSString stringWithFormat:#"%d",[cell.textLabel.text intValue] +1];
}
- (IBAction)subtractLabelText:(id)sender
{
cell = (UITableViewCell*)[sender superview];
if ( [[cell.textLabel text] intValue] == 0){
cell.textLabel.text = [NSString stringWithFormat:#"%d",[cell.textLabel.text intValue] +0];
}
else{
cell.textLabel.text = [NSString stringWithFormat:#"%d",[cell.textLabel.text intValue] -1];
//[myTableView reloadData];
}
}
You need something like this, where you are storing the values outside the cells. This is because the cells get reused and are not good long term storage.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
subBtn = [[UIButton alloc]init];
subBtn=[UIButton buttonWithType:UIButtonTypeRoundedRect];
[subBtn setFrame:CGRectMake(200,20,55,35)];
[subBtn addTarget:self action:#selector(addLabelText:indexPath.row) forControlEvents:UIControlEventTouchUpInside];
[subBtn setTitle:#"+" forState:UIControlStateNormal];
[subBtn setEnabled:YES];
[cell addSubview:subBtn];
}
// we're loading the value from the array each time the cell is displayed.
cell.textLabel.text = [cellLabelValues objectAtIndex:indexPath.row];
return cell;
}
- (IBAction)addLabelText:(int)currentRow{
NSString *newValue = [NSString stringWithFormat:#"%d",[[[cellLabelValues objectAtIndex:currentRow] intValue] +1];
// we update the value in the array since this is the source of the data for the cell
[cellLabelValues replaceObjectAtIndex:currentRow withObject:newValue];
// now reload to get the new value
[myTableView reloadData];
}
i wants just know.... to add buttons in each cell in table row.....programmatically in runtime
and also wants identify the button when clicked....
i write little code..here....
//---insert individual row into the table view---
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:[NSString stringWithFormat:#"Cell %i",indexPath.section]];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:[NSString stringWithFormat:#"Cell %i",indexPath.section]] autorelease];
}
NSLog(#"i am here in table function..........now");
//cell.textLabel.text = [data objectAtIndex: indexPath.row];
search_items *pro = [searchCount objectAtIndex:[indexPath row]];
cell.textLabel.text = pro.s_showroomName;
UIButton* aButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[aButton setTag:[indexPath row]];
[aButton addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:aButton];
return cell;
}
-(void)buttonClicked:(UIButton*)sender {
int tag = sender.tag;
///and rest code here.....
}
this code not work properly....:)
please give me solution :)
thanks in advance.....please give me any tutorial also..
set the frame for your button like this..
aButton.frame = CGRectMake(0, 0,150,44);
chck the question you may get some help runtime adding button and calling methods on them. iPhone: Add UIButton's horizontally with scrollbar provision in a View or TableView?
I have a tableview in which I am trying to place a button with an image and a label. I want to change the image of the button once clicked.
Here's the code:
- (UITableViewCell *)tableView:(UITableView *)_tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
checkedImg = [UIImage imageNamed:#"buttonUnChecked1.png"];
UITableViewCell *cell = [_tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}
//Set up the cell...
NSString *cellValue = [suggestions objectAtIndex:indexPath.row];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
check = [UIButton buttonWithType:UIButtonTypeCustom];
check.frame=CGRectMake(0,35,20,20);
[check setImage:checkedImg forState:UIControlStateNormal];
[check addTarget:self action:#selector(checkClicked:) forControlEvents: UIControlEventTouchUpInside];
[cell.contentView addSubview:check];
cellContent = [[UILabel alloc]initWithFrame:CGRectMake(40,32,500,25)];
cellContent.text = cellValue;
[cell.contentView addSubview:cellContent];
return cell;
}
-(void)checkClicked:(UIButton *)b
{
checkedImg = [UIImage imageNamed:#"buttonChecked1.png"];
[check setImage:checkedImg forState:UIControlStateNormal];
}
By doing this, the image of the buttons are getting changed but only the last one and not the one clicked. I know the reason behind it, but I don't know how to achieve what I want.
A structured way to get the result you're looking for:
Make a UIView subclass that for your table cells (containing a button and label). You instantiate these custom views and set them as your contentView for each table cell in cellForRowAtIndexPath.
Each of your custom views listens for its own button being pressed. When it was pressed, it toggles its state and tells the main viewcontroller (via a delegate method) that it was toggled. The main view controller calls reloadData on the cell in question to cause it to be reloaded with the correct appearance.
Note that this approach requires you to tell each of the custom views which index path it is rendering for in the table -- that way it can inform the main view controller's delegate method -- this info is needed for triggering a reload of the appropriate cell.
Btw, I presume you want to look at the state of the buttons in your table when the user is done with editing, and your current approach doesn't capture the state stuff very explicitly -- you'd have to iterate over your buttons, or add selected items to a mutable array, or something.
The easy answer to your problem is to change your checkClicked: method to this:
-(void)checkClicked:(UIButton *)b
{
[b setImage:[UIImage imageNamed:#"buttonChecked1.png"] forState:UIControlStateNormal];
}
But you should also adjust your tableView:cellForRowAtIndexPath: method to avoid creating the button repeatedly and to clean up some memory issues like this:
- (UITableViewCell *)tableView:(UITableView *)_tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [_tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
UIButton *checkBtn = [UIButton buttonWithType:UIButtonTypeCustom];
checkBtn.frame = CGRectMake(0,35,20,20);
[checkBtn setImage:[UIImage imageNamed:#"buttonUnChecked1.png"]; forState:UIControlStateNormal];
[checkBtn addTarget:self action:#selector(checkClicked:) forControlEvents: UIControlEventTouchUpInside];
[cell.contentView addSubview:checkBtn];
UILabel *cellContentLbl = [[UILabel alloc]initWithFrame:CGRectMake(40,32,500,25)];
cellContentLbl.tag = 1;
[cell.contentView addSubview:cellContentLbl];
[cellContentLbl release];
}
//Set up the cell...
NSString *cellValue = [suggestions objectAtIndex:indexPath.row];
cellContent = (UILabel *)[cell viewWithTag:1];
cellContent.text = cellValue;
return cell;
}
i have a strange issue with my UITableView...I add a UIButton as a subview to each cell , but when any of the cells gets out of view something happens, and when i scroll up again , i can see that the UIButton background images of some cells are overlapping !
The cellForRowAtIndexPath method i use contains the following code , which adds the UIButton instances
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MyCell"];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:#"MyCell"];
[cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];
UIFont *titleFont = [UIFont fontWithName:#"Arial-BoldMT" size:14.0];
[[cell textLabel] setFont:titleFont];
[cell autorelease];
}
if([cell viewWithTag:indexPath.row]==nil){
UIButton *buttonLeft = [UIButton buttonWithType:UIButtonTypeCustom];
buttonLeft.tag=indexPath.row;
if ([[myArray objectAtIndex:indexPath.row] isEqualToString:#"item1"]) {
[buttonLeft addTarget:self action:#selector(doThat:) forControlEvents:UIControlEventTouchUpInside];
[buttonLeft setBackgroundImage:[UIImage imageNamed:#"item1.png"] forState:UIControlStateNormal];
[buttonLeft setFrame: CGRectMake( 5.0f, 6.2f, 30.0f, 30.0f)];
}else{
[buttonLeft addTarget:self action:#selector(doThat:) forControlEvents:UIControlEventTouchUpInside];
[buttonLeft setBackgroundImage:[UIImage imageNamed:#"item2.png"] forState:UIControlStateNormal];
[buttonLeft setFrame: CGRectMake( 5.0f, 6.2f, 30.0f, 30.0f)];
}
[cell addSubview:buttonLeft];
}
cell.textLabel.text=[NSString stringWithFormat:#" %#",[myArray objectAtIndex:indexPath.row]];
return cell;
}
Apparently , this code for some reason adds the UIButton everytime the cell is displayed. I want each button subview to be added only once..
What am i doing wrong ?
Your help is much appreciated
That is because the table view reuses cells for performance reasons. Therefore, the cellForRowAtIndexPath: method, correctly implemented like yours, returns cells that already exist and only creates a new one if there is no reusable cell available.
Put all your button-related code within if (cell == nil) {}, so that the button is only added to "fresh" cells and it should work!