I want to change image on the button, when button click. That button is placed in table cell. Image is changing successfull. But when table scroll by default after every 5 cell button image also changed, while I didn't changed it. Means new cells in table, unwilling change. This cell is reusable, and created by storyboard.
How to use that button as switch button. How can I achieve this.
- (NSIndexPath *)indexPathWithSubview:(UIView *)subview {
while (![subview isKindOfClass:[UITableViewCell self]] && subview) {
subview = subview.superview;
}
return [self.table indexPathForCell:(UITableViewCell *)subview];
}
- (IBAction)btnCheckedCellPressed:(id)sender{
NSIndexPath *myIP = [self indexPathWithSubview:(UIButton *)sender];
MyWantsTableViewCell* cell = (MyWantsTableViewCell *)[self.table cellForRowAtIndexPath:myIP];
if (cell.btnEdit.currentImage == [UIImage imageNamed:#"checkbox-active"]) {
[cell.btnEdit setImage:[UIImage imageNamed:#"checkbox-deactive"]
forState:UIControlStateNormal];
} else {
[cell.btnEdit setImage:[UIImage imageNamed:#"checkbox-active"]
forState:UIControlStateNormal];
}
// [self.table beginUpdates];
// [self.table reloadRowsAtIndexPaths:#[myIP] withRowAnimation:UITableViewRowAnimationFade];
// [self.table endUpdates];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
MyWantsTableViewCell *cell=nil;
static NSString *AutoCompleteRowIdentifier = #"MyWantsTableViewCellEdit";
cell = [tableView dequeueReusableCellWithIdentifier:AutoCompleteRowIdentifier forIndexPath:indexPath];
if (cell == nil)
{
cell = [[MyWantsTableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault reuseIdentifier:AutoCompleteRowIdentifier];
[[AsyncImageLoader sharedLoader] cancelLoadingImagesForTarget:cell.imgProduct];
}
cell.selectionStyle = UITableViewCellAccessoryNone;
cell.btnEdit.tag = indexPath.row;
return cell;
}
Use simple way as I have described below, and use an object to keep the current selection, since it will go if you scroll the UITableView
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
[cell.btnEdit setImage:[UIImage imageNamed:#"checkbox-active"]
forState:UIControlStateNormal];
[cell.btnEdit setImage:[UIImage imageNamed:#"checkbox-deactive"]
forState:UIControlStateSelected];
MyClass *obj=[arr objextAtIndex:indexPath.row];
cell.btnEdit.selected=obj.selected;
}
- (IBAction)btnCheckedCellPressed:(id)sender{
NSIndexPath *myIP = [self indexPathWithSubview:(UIButton *)sender];
MyWantsTableViewCell* cell = (MyWantsTableViewCell *)[self.table cellForRowAtIndexPath:myIP];
cell.btnEdit.selected=!cell.btnEdit.selected;
MyClass *obj=[arr objectAtIndex:myIP.row];
obj.selected=!obj.selected;
}
Sample
Find sample for help here
1.. Take a NSInteger variable like "selectedBtn" and initialize it with -1, in viewDidLoad().
2.. go to cellForRowAtIndexPath() set button.tag == indexpath.row;
3.. Now in btnCheckedCellPressed() set that selectedBtn variable with tag value of that sender button.
4.. Now again go to cellForRowAtIndexPath() and place a check
if(cell.btnEdit.tag == selectedBtn)
// set selected image on button
else
// set unselected Image
Related
i have a tableview in Main Controller which has its custom cell that contains 3-4 button.. see screenshot
when button getpressed it populate a small tableview , when i select row of new tableview it not works a i expected see screenshot
Now issue is its setting selected value of new tableview to oldtableview same index
here's code :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *MyIdentifier = #"FollowUp";
UITableViewCell *cell ;//= [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier] ;
if (tableView == tblScribedBy) {
[cell.textLabel setText:[arrScribedBy objectAtIndex:indexPath.row]];
[cell.textLabel sizeToFit];
}
if (tableView == tblDropDown) {
if ([btnCLicked isEqualToString:#"Cell"]) {
[cell.textLabel setText:[totalRows objectAtIndex:indexPath.row]];
[cell.textLabel sizeToFit];
}
else if ([btnCLicked isEqualToString:#"Drop"]){
[cell.textLabel setText:[arrFUDrop objectAtIndex:indexPath.row]];
}
}
if (tableView == tblView) {
FUCellView * cell = [tableView dequeueReusableCellWithIdentifier:#"myCell"];
if (!cell)
{
[tblView registerNib:[UINib nibWithNibName:#"FUCellView" bundle:nil] forCellReuseIdentifier:#"myCell"];
cell = [tblView dequeueReusableCellWithIdentifier:#"myCell"];
}
[cell.btntfFUCell addTarget:self action:#selector(actionTfCellFU:) forControlEvents:UIControlEventTouchUpInside];
[cell.btntfFUCell setTag:indexPath.row];
[cell.btnDropFU addTarget:self action:#selector(actionDropFU:) forControlEvents:UIControlEventTouchUpInside];
[cell.btnDropFU setTag:indexPath.row];
return cell;
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
FUCellView *cell = (FUCellView *)[tblView cellForRowAtIndexPath:indexPath];
if ( tableView == tblScribedBy) {
[self.btnScribedBy setTitle:[NSString stringWithFormat:#" %#",[arrScribedBy objectAtIndex:indexPath.row]] forState:UIControlStateNormal ];
[tblScribedBy setHidden:TRUE];
}
else if (tableView == tblDropDown) {
if ([btnCLicked isEqualToString:#"Cell"]) {
[cell.tfFUCell setText:[totalRows objectAtIndex:indexPath.row]];
}
else if ([btnCLicked isEqualToString:#"Drop"]){
[cell.btnDropFU setTitle:[arrFUDrop objectAtIndex:indexPath.row] forState:UIControlStateNormal];
}
[tblDropDown setHidden:YES];
}
}
//----- Action for Buttons
-(void)actionTfCellFU:(UIButton *)sender
{
btnCLicked = #"Cell";
[tblDropDown setHidden:FALSE];
[tblDropDown reloadData];
}
-(void)actionDropFU:(UIButton *)sender
{
btnCLicked = #"Drop";
[tblDropDown setHidden:FALSE];
[tblDropDown reloadData];
}
FUCellView *cell = (FUCellView *)[tblView cellForRowAtIndexPath:indexPath];
This line is being used to get the cell to update, but it's using the index path selected on the second table view to get the target cell on the first table view. Hence you get an index error and the wrong cell is updated.
When actionDropFU: is called you need to determine a way of storing, as an instance variable, the index path of the cell which was selected. This is the index path on table 1 and is the one you want to use to update when setting the results of the selection from the second table later. In general you shouldn't be updating the cell directly, you should be updating your data model.
The best option for this is to not just add a target and selector to the buttons on your cells. Instead, subclass the cell and add properties to it so you can access them later when it is interacted with. The cell should be the target of the button clicks and it should call back to the view controller (as the cell delegate or target) when the buttons are tapped, passing the configured data (the index path).
Trying to implement the checkmark for UITableView.
Checkmark for UITableView Cell is not selecting to all row, when scroll tableview
its not not enable.
Below is my code which i Implemented.
IndexButton is UIButton Class which added index init.
-(void)selectAllAction:(IndexedButton *)sender{
for (int rowIndex = 0; rowIndex < [array_MedicineList count]; rowIndex++) {
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:rowIndex inSection:0];
UITableViewCell *cell = [tbl_ProductList cellForRowAtIndexPath:indexPath];
IndexedButton *btn_SelectItem = (IndexedButton *)[cell viewWithTag:TAG_SELECTEDITEM];
[btn_SelectItem setBackgroundImage:[UIImage imageNamed:#"checkMark"] forState:UIControlStateNormal];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *productListTableViewCell = #"ProductListTableViewCell";
ProductListTableViewCell *cell = (ProductListTableViewCell *)[tableView dequeueReusableCellWithIdentifier:productListTableViewCell];
if (cell == nil){
cell = [[ProductListTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:productListTableViewCell];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
IndexedButton *btn_SelectItem = [IndexedButton buttonWithType:UIButtonTypeCustom];
btn_SelectItem.frame = CGRectMake(10,52,32,32);
[btn_SelectItem setBackgroundImage:[UIImage imageNamed:#"uncheckMark"] forState:UIControlStateNormal];
[btn_SelectItem addTarget:self action:#selector(selectItemAction:)forControlEvents:UIControlEventTouchUpInside];
btn_SelectItem.index = (int)indexPath.row;
btn_SelectItem.tag = TAG_SELECTEDITEM;
[cell addSubview:btn_SelectItem];
}
IndexedButton *btn_SelectItem = (IndexedButton *)[cell viewWithTag:TAG_SELECTEDITEM];
btn_SelectItem.index = (int)indexPath.row;
cell.backgroundColor = [UIColor clearColor];
return cell;
}
#All
Need suggestion, how to go forward to implement the check mark for tableview.
I would suggest you to use cell with accessory view with UITableViewCellAccessoryCheckmark type to show all cells selected/ few cells selected/ none of the cells selected.
Also, you must keep the state for each cell index within a section, whether it's selected or not as
// keeps info for selected rows in a section in mutable index set as
NSMutableIndexSet *selctedCellsInSection;
// initialize the above set instance
selctedCellsInSection = [[NSMutableIndexSet alloc] init];
//Inside cell for row at index path
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
if ([selctedCellsInSection containsIndex:indexPath.row])
[cell setAccessoryType:UITableViewCellAccessoryCheckmark];
else
[cell setAccessoryType:UITableViewCellAccessoryNone];
// customize cell as per your requirements
return cell;
}
You need to hold the information about a cell's checkmark whether it needs to be shown or not in selctedCellsInSection set as -
Use [selctedCellsInSection addIndex:rowToSelect]
// to add cell index on which checkmark needs to be shown
Use [selctedCellsInSection removeIndex:rowToUnselect]
// to add cell index on which checkmark should not be shown
After, customizing the data source selctedCellsInSection(which keeps information about selected/ unselected cell) reload the tableview.
Reloading the table will reflect the selected cells with Cell's Accessory Checkmark.
In your case as you need show check mark on all cell, you can do so as-
-(void)showCheckMarkOnAllCells
{
for (int rowIndex = 0; rowIndex < [array_MedicineList count]; rowIndex++)
{
[selctedCellsInSection addIndex: rowIndex];
}
[tableView reloadData];
}
#interface BRNCategoryViewController ()
{
NSMutableArray *arySelectCategory;
NSMutableArray *aryCategory;
}
- (void) viewDidLoad
{
arySelectCategory=[NSMutableArray new];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return aryCategory.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
BRNCategoryCell *cell=[[BRNCategoryCell alloc]initWithOwner:self];
if ([arySelectCategory containsObject:[aryCategory objectAtIndex:indexPath.row]])
{
cell.imgBoxView.image=[UIImage imageNamed:#"checkMark"];
}
else
{
cell.imgBoxView.image=[UIImage imageNamed:#"uncheckMark"];
}
cell.lblTitle.textColor=Rgb2UIColor(127, 127, 127);
cell.lblTitle.font=[ASCustomClass FontWithSize:20.0];
cell.lblTitle.text=aryCategory[indexPath.row];
cell.backgroundColor=[UIColor clearColor];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
if ([arySelectCategory containsObject:[aryCategory objectAtIndex:indexPath.row]])
{
[arySelectCategory removeObject:[aryCategory objectAtIndex:indexPath.row]];
}
else
{
[arySelectCategory addObject:[aryCategory objectAtIndex:indexPath.row]];
}
[tblEventCategory reloadData];
}
I realize this is a common problem but I'm just not getting it. I have a button that when pressed on a cell, changes to a check mark. However, when pressed it changes other reused cell's image to a check mark as well. I'm using a cell's delegate to manipulate local data on the tableView's VC.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// Configure the cell...
static NSString *ReusableIdentifier = #"Cell";
SetListTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ReusableIdentifier forIndexPath:indexPath];
cell.delegate = self;
if ([self.selectedRows containsIndex:indexPath.row]) {
[cell.plusButton setBackgroundImage:checkImage forState:UIControlStateNormal];
}
else {
[cell.plusButton setBackgroundImage:plusImage forState:UIControlStateNormal];
}
cell.tag = indexPath.Row
return cell;
}
Method in custom cell's class.
- (IBAction)addSongButtonPressed:(UIButton *)sender
{
[self.delegate addSongButtonPressedOnCell:self];
UIImage *checkImage = [UIImage imageNamed:#"check.png"];
[self.plusButton setBackgroundImage:checkImage forState:UIControlStateNormal];
}
Method from the cell's delegate.
-(void)addSongButtonPressedOnCell:(id)sender
{
NSInteger index = ((UIButton *)sender).tag;
NSMutableDictionary *track = [self.searchTracks objectAtIndex:indexPath];
[self.selectedRows addIndex:indexPath];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1; //count of section
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 30; //count number of row from counting array hear cataGorry is An Array
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *testword=#"pass";
if ([testword isEqualToString:#"pass"]) {
static NSString *MyIdentifier = #"cell1";
TextTableViewCell *cell ;
cell= [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
cell.lblText.text=[NSString stringWithFormat:#"textcelll= %i", indexPath.row+1];
cell.btnTextbox.tag=indexPath.row;
[cell.btnTextbox addTarget:self action:#selector(customActionPressed:) forControlEvents:UIControlEventTouchUpInside];
return cell;
}else{
static NSString *MyIdentifier1 = #"cell2";
ImageTableViewCell *cell1 = [tableView dequeueReusableCellWithIdentifier:MyIdentifier1];
return cell1;
}
}
-(void)customActionPressed:(UIButton*)sender{
CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:self.tableView1];
NSIndexPath *indexPath = [self.tableView1 indexPathForRowAtPoint:buttonPosition];
TextTableViewCell *cell = (TextTableViewCell*)[self.tableView1 cellForRowAtIndexPath:indexPath];
if (indexPath != nil)
{
int currentIndex = indexPath.row;
NSLog(#"currentIndex == %d",currentIndex);
int tableSection = indexPath.section;
NSLog(#"tableSection == %d",tableSection);
}
if (!cell.btnTextbox.isSelected ){
cell.btnTextbox.selected=YES;
[cell.btnTextbox setImage:[UIImage imageNamed:#"checkClick.png"] forState:UIControlStateNormal];
NSLog(#"button tag %i",cell.btnTextbox.tag);
NSLog(#"check click");
}else{
cell.btnTextbox.selected=NO;
[cell.btnTextbox setImage:[UIImage imageNamed:#"check.png"] forState:UIControlStateNormal];
NSLog(#"check ");
}
in simulator , when i am clicked the button in first row (indexpath.row=0) then i am scrolling tableview, button click will auto display in 7th row (indexpath.row=6)
Question is ,i want to know , what happened in really and how to avoid this (when i'm scrolling)?
Since cells are being reused, you have to (in your cellForRowAtIndexPath) to set image to one state or another (to set one image or another).
What really happen is that you set Image for one cell but that cell is being reused through whole table. You use only 5(lets say that is how much you cells can fit into one screen) cells and when you load next you actually reuse the one with an image.
So, in your cellForRowAtIndexPath you will have to check if the button state is selected or not and then assign appropriate image.
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *testword=#"pass";
if ([testword isEqualToString:#"pass"]) {
static NSString *MyIdentifier = #"cell1";
TextTableViewCell *cell ;
cell= [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
cell.lblText.text=[NSString stringWithFormat:#"textcelll= %i", indexPath.row+1];
cell.btnTextbox.tag=indexPath.row;
if (cell.btnTextbox.isSelected ){
[cell.btnTextbox setImage:[UIImage imageNamed:#"checkClick.png"] forState:UIControlStateNormal];
}else{
[cell.btnTextbox setImage:[UIImage imageNamed:#"check.png"] forState:UIControlStateNormal];
}
[cell.btnTextbox addTarget:self action:#selector(customActionPressed:) forControlEvents:UIControlEventTouchUpInside];
return cell;
}else{
static NSString *MyIdentifier1 = #"cell2";
ImageTableViewCell *cell1 = [tableView dequeueReusableCellWithIdentifier:MyIdentifier1];
return cell1;
}
}
For completness sake, I would also suggest you to use Accessory type as well as Xib files for these kind of cells. You can set it in storyboard under accessory dropdown or through code:
cell.accessoryType = UITableViewCellAccessoryCheckmark;
I am fairly new to Objective C programming, and have a UITableView setup with a custom cell. I want to make it so a user can touch a button that will add another cell, and this button will appear in the last cell only. Currently, it is not showing up. Here is the code that I am using. I have created the button within the custom cell, and used "setHidden:YES" to hide it within the cell itself. I am trying "setHidden:NO" to make the button appear in the TableView code, but it is not working. I thought maybe it had something to do with reloading the cell, but I am not sure if I am going in the right direction with this or not. I would appreciate any help on this, thanks.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{workoutTableViewCell *cell = (workoutTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// Configure the cell...
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
[cell.addButton setTitle:(NSString *)indexPath forState:UIControlStateApplication];
[cell.textLabel setText:[NSString stringWithFormat:#"Row %i in Section %i", [indexPath row], [indexPath section]]];
NSInteger sectionsAmount = [tableView numberOfSections];
NSInteger rowsAmount = [tableView numberOfRowsInSection:[indexPath section]];
if ([indexPath section] == sectionsAmount - 1 && [indexPath row] == rowsAmount - 1) {
NSLog(#"Reached last cell");
[cell.addButton setHidden:NO];
if (lc == NO)
{[[self tableView] reloadData];
lc = YES;
}
}
return cell;
}
Following UITableViewDataSource method will help you to return exact number of rows available in section. Here you need to return additional as you want to have last as your button.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return yourRowCount + 1;
}
Now in folowing method you will check row number using indexpath.row as
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *lastCellIdentifier = #"LastCellIdentifier";
static NSString *workoutCellIdentifier = #"WorkoutCellIdentifier";
if(indexPath.row==(yourRowCount+1)){ //This is last cell so create normal cell
UITableViewCell *lastcell = [tableView dequeueReusableCellWithIdentifier:lastCellIdentifier];
if(!lastcell){
lastcell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:lastCellIdentifier];
CGRect frame = CGRectMake(0,0,320,40);
UIButton *aButton = [UIButton buttonWithType:UIButtonTypeCustom];
[aButton addTarget:self action:#selector(btnAddRowTapped:) forControlEvents:UIControlEventTouchUpInside];
aButton.frame = frame;
[lastcell addSubview:aButton];
}
return lastcell;
} else { //This is normal cells so create your worktouttablecell
workoutTableViewCell *cell = (workoutTableViewCell *)[tableView dequeueReusableCellWithIdentifier:workoutCellIdentifier];
//Configure your cell
}
}
Or you can do like create UIView programatically and set it as FooterView as suggested by #student in comment code would look like,
CGRect frame = CGRectMake(0,0,320,40);
UIView *footerView = [[UIView alloc] initWithFrame:frame];
UIButton *aButton = [UIButton buttonWithType:UIButtonTypeCustom];
[aButton addTarget:self action:#selector(btnAddRowTapped:) forControlEvents:UIControlEventTouchUpInside];
aButton.frame = frame;
[footerView addSubView:aButton];
[yourTableNmae setTableFooterView:footerView];
Declare method as follow
-(IBAction)btnAddRowTapped:(id)sender{
NSLog(#"Your button tapped");
}
if ([indexPath section] == sectionsAmount - 1 && [indexPath row] == rowsAmount - 1) {
NSLog(#"Reached last cell");
[cell.addButton setHidden:NO];
} else {
[cell.addButton setHidden:YES];
}
Replace this code in your program.
If you know your number of cells in the uitable and you wish to just know when the last row will appear, you could implement the following delegate method
(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
this method tells the delegate table view is about to draw cell for particular row, simple compare your row with table rowcount.