In Collection view i am select the one cell but it is selected multiple cells.
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
CustomCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"Cell" forIndexPath:indexPath];
cell.Selectitems.tag=indexPath.row;
[cell.Selectitems addTarget:self action:#selector(selectitem:) forControlEvents:UIControlEventTouchUpInside];
}
-(void)selectitem :(UIButton *)sender{
if ([sender isSelected]) {
[sender setSelected: NO];
cell.check = YES;
[cell.Selectitems setBackgroundImage:[UIImage imageNamed:#"product-uncheck.png"] forState:UIControlStateNormal];
}else{
[sender setSelected: YES];
cell.check = YES;
[cell.Selectitems setBackgroundImage:[UIImage imageNamed:#"product-check.png"] forState:UIControlStateNormal];
}
}
Check bellow my image link
[1]: http://i.stack.imgur.com/WIgDH.png
Here is the complete code which may satisfy your requirement for checkbox with collectionview
https://www.dropbox.com/s/e43zk55surlwjlk/CollectionCkeck.zip?dl=0
When you clicked on second cell you are not changing image on first cell.
So make sure that if you clicked on any cell change the image as product-check.png and previous cell image as product-uncheck.png
Do like this When Button is Pressed
-(void)selectitem :(UIButton *)sender{
//Get Index path from Button Tag
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:sender.tag inSection:0];
// get Cell instance and than do whatever you want with Cell items
CustomCell *cell = *cell = [self.collectionView cellForItemAtIndexPath:indexPath];
if ([cell.Selectitems isSelected]) {
[cell.Selectitems setSelected: NO];
cell.check = YES;
[cell.Selectitems setBackgroundImage:[UIImage imageNamed:#"product-uncheck.png"] forState:UIControlStateNormal];
}else{
[cell.Selectitems setSelected: YES];
cell.check = YES;
[cell.Selectitems setBackgroundImage:[UIImage imageNamed:#"product-check.png"] forState:UIControlStateNormal];
}
}
i hope this will solve your problem .
Related
I have two UIButton in a UITableViewCell subclass, and in view controller class i have have its selector method, but on clicking on button it always gives the last tag value assigned inside cellForRowAtIndexPath method.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"cell";
customCell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
customCell.oneYear.tag = indexPath.row;
customCell.threeYearButton.tag = indexPath.row + 50;
[customCell.oneYear addTarget:self
action:#selector(oneYearButtonAction)
forControlEvents:UIControlEventTouchUpInside];
[customCell.threeYearButton addTarget:self
action:#selector(threeYearButtonAction)
forControlEvents:UIControlEventTouchUpInside];
[customCell setSelectionStyle:UITableViewCellSelectionStyleNone];
It works fine if i use IBAction, but I have to use selector method, which gives above issue.
Kindly help.
You need to create new instance of your custom class with cellForRowAtIndexPath instead of that you are using the same instance customCell.
Instead of this:
customCell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
You need to create new object like this:
CustomCellName *customCell = (CustomCellName*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
Edit: Instead of using tag with your cell's button action you can try like this way.
-(void)oneYearButtonAction:(UIButton*)sender {
CGPoint center= sender.center;
CGPoint rootViewPoint = [sender.superview convertPoint:center toView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:rootViewPoint];
CustomCellName *currentCell = [self.tableView cellForRowAtIndexPath:indexPath];
}
You have declared the cell out of the cellForRow method. If you do this your cell object will contains the last object thats why your button always have last tag.
Solution
Declare your object for cell like this in cellForRow
MyCustomCell *customCell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; //what ever your class name be I am says MyCustomCell.
NOTE: If you want to use cell object in any other method then there will be lots of other properties are available.
HOW TO GET CELL OBJECT IN BUTTON ACTION METHOD
- (IBAction)btnShowClicked:(UIButton*)sender {
CGPoint buttonPosition = [sender convertPoint:CGPointZero tblObject];
NSIndexPath *indexPath = [tblObject indexPathForRowAtPoint:buttonPosition];
MyCustomCell *customCell = [tblObject cellForRowAtIndexPath:indexPath];
I know you have already resolved the issue. Still posting for someone who might need complete code. FYI, you can use the same method for both buttons, you can directly check in that method which button was clicked with btn.tag as button object is already passed.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
customTableCell *customCell = [tableView dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
[customCell.btn1 setTitle:[NSString stringWithFormat:#"Button %ld",(long)indexPath.row]
forState:UIControlStateNormal];
[customCell.btn2 setTitle:[NSString stringWithFormat:#"Button %ld",(long)indexPath.row+10]
forState:UIControlStateNormal];
[customCell.btn1 setTag:indexPath.row];
[customCell.btn2 setTag:indexPath.row+10];
[customCell.btn1 addTarget:self action:#selector(btnClicked:) forControlEvents:UIControlEventTouchUpInside];
[customCell.btn2 addTarget:self action:#selector(btnClicked:) forControlEvents:UIControlEventTouchUpInside];
return customCell;
}
-(void) btnClicked:(UIButton *) btn {
UIAlertController *alertC = [UIAlertController alertControllerWithTitle:#"" message:[NSString stringWithFormat:#"Button %ld tapped",(long)btn.tag] preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *action = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleCancel handler:nil];
[alertC addAction:action];
[self presentViewController:alertC animated:true completion:nil];
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 5;
}
I have create this redio button in cellForRowAtIndexPath
btnper = [UIButton buttonWithType:UIButtonTypeCustom];
btnper.frame = CGRectMake(10, 10, 50, 30);
btnper.tag = indexPath.row;
btnper.titleLabel.font = [UIFont systemFontOfSize:13.0f];
[btnper setImage:[UIImage imageNamed:#"Radiooff1"]
forState:UIControlStateNormal];
[btnper setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[btnper setTitle:#" 0%" forState:UIControlStateNormal];
[btnper addTarget:self action:#selector(btnperPress:)
forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:btnper];
this is my Action Method to identify which cell button is pressed
- (IBAction)btnperPress:(UIButton *)sender {
NSInteger selectedCheckBox = sender.tag;
NSLog (#"%d",selectedCheckBox);
}
I want collectionview cell in which i placed custom button checkboxes used for adding member to the group.multiselection is also possible.but when i select particular checkbox alongwith it the other checkbox which is not visible is also selected which is at same indexpath from lastvisible cell below is my code
`
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
CGCell *cell = [_CGCol dequeueReusableCellWithReuseIdentifier:#"CELL" forIndexPath:indexPath];
[cell.btn addTarget:self action:#selector(CheckUncheckFunctionality:) forControlEvents:UIControlEventTouchUpInside];
cell.btn.tag = indexPath.row;
return cell;
}
-(void)CheckUncheckFunctionality:(id)sender
{
UIButton *btn = (UIButton *)sender;
if (btn.selected) {
[btn setImage:[UIImage imageNamed:#"unchacked.png"] forState:UIControlStateNormal];
}
else{
[btn setImage:[UIImage imageNamed:#"checked.png"] forState:UIControlStateNormal];
}
}
`
declare global Array and inititlize
NSMutableArray * ArrCheckIndexs=[[NSMutableArray alloc] init];
for (int i=0; i<no.ofcell; i++)
{
[ArrCheckIndexs addObject:#"0"];
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
CGCell *cell = [_CGCol dequeueReusableCellWithReuseIdentifier:#"CELL" forIndexPath:indexPath];
[cell.btn addTarget:self action:#selector(CheckUncheckFunctionality:) forControlEvents:UIControlEventTouchUpInside];
cell.btn.tag = indexPath.row;
return cell;
}
-(void)CheckUncheckFunctionality:(id)sender
{
UIButton *btn = (UIButton *)sender;
if ([[ArrCheckIndexs objectAtIndex:btn.tag] isEqualToString:#"1"])
{
[btn setImage:[UIImage imageNamed:#"unchacked.png"] forState:UIControlStateNormal];
[ArrCheckIndexs replaceObjectAtIndex:btn.tag withObject:#"0"];
}
else
{
[btn setImage:[UIImage imageNamed:#"checked.png"] forState:UIControlStateNormal];
[ArrCheckIndexs replaceObjectAtIndex:btn.tag withObject:#"1"];
}
}
The cell might be getting reused. And Since you are not updating the cells when they are returned by the cellForItemAtIndexPathmethod they are in their last updated state. Solution : -
I presume you are using models for cell information
Add an boolean flag in the model which will store whether the item is checked or not. Initially false
When you will return the cell check for the model for the flag value for the cells. and update the button state accordingly.
I am trying to create a custom cell with favorite button on it. Its working fine but I think reuse identifier is creating problem here. I have tried it in two ways and it is working fine in both.
Here is my first try:
When I am selecting the button, it is changing to yellow button and vice -versa. But after scrolling up or down,it is changing to its normal state again. Why?
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *CI=#"CELL";
UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:CI];
if(!cell) {
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CI];
}
favbtn=[[UIButton alloc]initWithFrame:CGRectMake(160, 10, 30, 35)];
[cell.contentView addSubview:favbtn];
[favbtn setBackgroundImage:[UIImage imageNamed:#"starr.png"] forState:UIControlStateNormal];
[favbtn addTarget:self action:#selector(fav:) forControlEvents:UIControlEventTouchUpInside];
cell.textLabel.text=[favdata objectAtIndex:indexPath.row];
return cell;
}
-(void)fav:(id)sender
{
if ([sender isSelected]) {
[sender setImage:[UIImage imageNamed:#"starr.png"] forState:UIControlStateNormal];
[sender setSelected:NO];
} else {
[sender setImage:[UIImage imageNamed:#"star.png"] forState:UIControlStateSelected];
[sender setSelected:YES];
}
}
Here is my second try:
Here every sixth cell is showing the same state.
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *CI=#"CELL";
UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:CI];
if(!cell) {
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CI];
favbtn=[[UIButton alloc]initWithFrame:CGRectMake(160, 10, 30, 35)];
[cell.contentView addSubview:favbtn];
[favbtn setBackgroundImage:[UIImage imageNamed:#"starr.png"] forState:UIControlStateNormal];
[favbtn addTarget:self action:#selector(fav:) forControlEvents:UIControlEventTouchUpInside];
cell.textLabel.text=[favdata objectAtIndex:indexPath.row];
}
return cell;
}
First of all modify this methods:
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *CI=#"CELL";
UIButton * favbtn;
UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:CI];
if(!cell)
{
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CI];
favbtn=[[UIButton alloc]initWithFrame:CGRectMake(160, 10, 30, 35)];
[cell.contentView addSubview:favbtn];
[favbtn setTag:11221133];
}
favbtn = [cell.contentView viewWithTag:11221133];
[favbtn setBackgroundImage:[UIImage imageNamed:#"starr.png"] forState:UIControlStateNormal];
[favbtn setImage:[UIImage imageNamed:#"starr.png"] forState:UIControlStateNormal];
[favbtn setImage:[UIImage imageNamed:#"star.png"] forState: UIControlStateSelected];
//Check selections here and if this index is selected make btn selected.
[favbtn addTarget:self action:#selector(fav:) forControlEvents:UIControlEventTouchUpInside];
cell.textLabel.text=[favdata objectAtIndex:indexPath.row];
cell.contentView.tag = indexPath.row;
return cell;
}
-(void)fav:(id)sender
{
UIButton * btn = (UIButton *)sender;
btn.selected = !btn.selected;
int index = [[btn superview] tag]; // use this index for storing selections
}
Then make a array for storing selections. Compare this selection in cellForRowAtIndexPath and make btn selected or not selected.
Hope this will help you.....
You need to understand the way the cell is being reused. When your cell is scrolled out of the screen, it will be reused for the cell that is entering the screen. Table view will keep calling the method cellForRowAtIndexPath every time they want to render the cell. In your code, you init a new favbtn all the time, so even if the cell already contains it and being reused, you will keep on adding more buttons into it. Here's my suggestions:
Create your own subclass of UITableViewCell. Let's say FavoriteCell. Put all your code to add the favorite button inside your subclass.
In ViewDidLoad register your cell with your table view. Something like this: [self.tableView registerClass:...] or [self.tableView registerNib:...] depending on if you have a nib file for your cell or not.
In cellForRowAtIndexPath, dequeue your cell as usual but you don't have to check if it's nil or not, and you don't have to create the favorite button since you already put it inside your subclass.
Just remember that, the method cellForRowAtIndexPath will be called all the time so your logic of inserting favorite button has to be done properly. Make sure that you only insert it once and update its property properly.
I Have a problem with my custom UItableViewCell. It's seems that all UIButton of UITableViewCell disappear on scroll. Specilay on my 25 cell. Any one have any idea ?
any help would be appreciated :)
That some code :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString* cellIdentifier = #"Cell";
Cell * __strong cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (!cell){
cell = [[Cell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
InfoObject __weak *obj = [_pos objectAtIndex:indexPath.row];
[cell configCell];
cell.id = obj.id;
{// EVENT ON BUTTON
[cell.checkbox addTarget:self action:#selector(checkup:) forControlEvents:UIControlEventTouchUpInside];
[cell.btnPaymentState addTarget:self action:#selector(changePaymentState:) forControlEvents:UIControlEventTouchUpInside];
}
{// SET BUTTON CHECKBOX
cell.checkbox.tag = indexPath.row;
[cell.checkbox setImage:[UIImage imageNamed:IMG_BLACK_UNCHECKBOX] forState:UIControlStateNormal];
[cell.checkbox setImage:[UIImage imageNamed:IMG_BLACK_CHECKBOX] forState:UIControlStateSelected];
[cell.checkbox setImage:[UIImage imageNamed:IMG_BLACK_CHECKBOX] forState:UIControlStateHighlighted];
}
{// SET BUTTON PAYMENT STATE
cell.btnPaymentState.tag = indexPath.row;
[cell.btnPaymentState setImage:[self getImageAssociateWithName:obj.stringPaymentState] forState:UIControlStateNormal];
[cell.btnPaymentState setImage:[self getImageAssociateWithName:obj.stringPaymentState] forState:UIControlStateSelected];
[cell.btnPaymentState setImage:[self getImageAssociateWithName:obj.stringPaymentState] forState:UIControlStateHighlighted];
}
[self SetSelectedBackgroundColorSelectedForFolderCellAtRow:indexPath.row
:obj.selected Cell: cell];
[cell.checkbox setSelected:obj.selected];
[self setCellColorTextOfObjectPrepare:cell withObj:obj];
return cell;
}
I solve my problem. The problem is that i was using Tag for my UIButton and the identifier was the same number tag of another UIView so when i was removing my UIView the UIButton disappear also. Thanks all for your answer.
Remove if (!cell)
And you're good to go.
I have a problem like this:
I have a table view. when i click on a cell (or row), the cell will add 2 more buttons and re-size.
This function it work fine!
The problem is when i click first row,
it creates 2 buttons and re-size
and then scroll down, another cell also display 2 buttons.
and this is my code for function of displaying button and resizing cell
I believe when scrolling down the table is reloaded and reset the indexPath, so 2 cells both display the buttons.
Anyone has any suggestion!?
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
tvcCategory *cell = (tvcCategory*)[tableView cellForRowAtIndexPath:indexPath];
NSLog(#"- %i ", indexPath.item);
if (selectedIndex.item != indexPath.item) {
[btnEdit removeFromSuperview];
[btnTransact removeFromSuperview];
objSession.catId = cell.lblId.text;
btnEdit = [UIButton buttonWithType:UIButtonTypeRoundedRect];
btnEdit.frame = CGRectMake(91, 72, 73, 35);
[btnEdit setTitle:#"Edit" forState:UIControlStateNormal];
[btnEdit setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[btnEdit setBackgroundImage:buttonImage forState:UIControlStateNormal];
[btnEdit setBackgroundImage:buttonImageHighlight forState:UIControlStateHighlighted];
[btnEdit addTarget:self action:#selector(moveToEditingScreen) forControlEvents:UIControlEventTouchUpInside];
btnTransact = [UIButton buttonWithType:UIButtonTypeRoundedRect];
btnTransact.frame = CGRectMake(176, 72, 95, 35);
[btnTransact setTitle:#"Transact" forState:UIControlStateNormal];
[btnTransact setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[btnTransact setBackgroundImage:buttonImage forState:UIControlStateNormal];
[btnTransact setBackgroundImage:buttonImageHighlight forState:UIControlStateHighlighted];
[btnTransact addTarget:self action:#selector(moveToTransactionScreen) forControlEvents:UIControlEventTouchUpInside];
[tableView reloadData];
[cell.contentView addSubview:btnEdit];
[cell.contentView addSubview:btnTransact];
lastClickedCell = cell;
self.selectedIndex = indexPath;
NSIndexPath* rowToReload = [NSIndexPath indexPathForRow:-1 inSection:0];
NSArray* rowsToReload = [NSArray arrayWithObjects:rowToReload, nil];
[tableView reloadRowsAtIndexPaths:rowsToReload withRowAnimation:UITableViewRowAnimationFade];
[tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
[tableView reloadData];
[tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryCheckmark;
}
}
I really appreciate
The problem that you are facing, like the guys has had exposed in the comments is that in the table view method you need to reuse cells to optimize the performance, so you need to take this cells that are already used and adjust it to your expected cell state.
Probably in your cellForRowAtIndexPath you are just taking care to allocate it and adjust it when you do not have a cell, you will need to adjust it, you have some options, like always adjust it to the initial state or you can check if the buttons are showed and only in this cases redesign your cell.
So in your class, at some point you have this method:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if(cell == nil){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
} else {
if([selectedIndex isEqual:indexPath]){
//Add your buttons and adjust the cell to show the extra buttons
} else {
if(your selected index isn't in the screen anymore){
[btnEdit removeFromSuperview];
[btnTransact removeFromSuperview];
}
//your others adjusts
}
}
}
EDIT:
[[yourTable indexPathsForVisibleRows] containsObject:selectedIndexPath];
This method return an array that you need to check if your selectedindex is inside it.
More about UITableView you can found at the documentation.