uitableview cell selection on button action - objective-c

My table view uses a custom class to create cells
MyCustomCell.h
#import <UIKit/UIKit.h>
#interface MyCustomCell : UITableViewCell
#end
MyCustomCell.m
#import "MyCustomCell.h"
#import <QuartzCore/QuartzCore.h>
#implementation MyCustomCell
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self)
{
// Initialization code
}
return self;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
self.selectionStyle = UITableViewCellSelectionStyleBlue;
// Configure the view for the selected state
}
- (void)layoutSubviews
{
[super layoutSubviews];
self.imageView.frame = CGRectMake(5,4,80,80);
self.imageView.layer.masksToBounds = YES;
self.imageView.layer.cornerRadius = 5.0f;
self.imageView.contentMode = UIViewContentModeScaleAspectFill;
float imgWidth = self.imageView.image.size.width;
if(imgWidth > 0)
{
self.textLabel.frame = CGRectMake(110,2,170,25);
self.detailTextLabel.frame = CGRectMake(110,18,200,25);
self.detailTextLabel.font = [UIFont boldSystemFontOfSize:12];
self.detailTextLabel.alpha = 0.0;
self.textLabel.font = [UIFont boldSystemFontOfSize:12];
self.textLabel.textColor = [UIColor colorWithRed:.2314 green:.3490 blue:.5961 alpha:1.0];
}
}
#end
and is use it like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
MyCustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[MyCustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
//cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height;
if ([UIScreen mainScreen].scale == 2.f && screenHeight == 568.0f)
{
UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[btn setBackgroundImage:[UIImage imageNamed:#"select2x.png"] forState:UIControlStateNormal];
[btn addTarget:self action:#selector(SelectButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
btn.frame = CGRectMake(110, 25, 63, 32);
//btn.tag = indexPath.row;
viewProfile = [UIButton buttonWithType:UIButtonTypeRoundedRect];
viewProfile.frame = CGRectMake(190, 25, 93, 32);
//[viewProfile setTitle:#"View Profile" forState:UIControlStateNormal];
[viewProfile setBackgroundImage:[UIImage imageNamed:#"viewProfile#2x.png"] forState:UIControlStateNormal];
[viewProfile addTarget:self action:#selector(viewProfileTapped:) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:viewProfile];
[cell.contentView addSubview:btn];
}
else
{
UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[btn setBackgroundImage:[UIImage imageNamed:#"select.png"] forState:UIControlStateNormal];
[btn addTarget:self action:#selector(SelectButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
btn.frame = CGRectMake(110, 25, 63, 32);
//btn.tag = indexPath.row;
viewProfile = [UIButton buttonWithType:UIButtonTypeRoundedRect];
viewProfile.frame = CGRectMake(190, 25, 93, 32);
//[viewProfile setTitle:#"View Profile" forState:UIControlStateNormal];
[viewProfile setBackgroundImage:[UIImage imageNamed:#"viewProfile.png"] forState:UIControlStateNormal];
[viewProfile addTarget:self action:#selector(viewProfileTapped:) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:viewProfile];
[cell.contentView addSubview:btn];
}
return cell;
}
Now each cell contains two buttons which perform an action(I do not make action on cell tap but on button tap) as created like above
Now what i want is when a user taps a button(say select button) in a particular cell, that particular cell only should become highlighted or shaded or coloured and when user taps a button in another cell, that cell should become highlighted making the previous cell unhighlighted. I have tried storing previous and next indexpath's in 2 different variables but not able to work on them to achieve what i want.
- (void)SelectButtonTapped:(UIButton *)button
{
UITableViewCell *cell = (UITableViewCell *)button.superview.superview;
NSIndexPath *indexPath = [homeTable indexPathForCell:cell];
// UITableViewCell *cell1 = [homeTable cellForRowAtIndexPath:indexPath];
//currentSelection = indexPath.row;
//MyCustomCell *cell1 = (MyCustomCell *)[homeTable cellForRowAtIndexPath:indexPath];
[[homeTable delegate]tableView:homeTable didSelectRowAtIndexPath:indexPath];
//MyCustomCell *cell1 = (MyCustomCell *)[homeTable cellForRowAtIndexPath:indexPath];
/*if(currentSelection == 0)
{
[cell1 setSelected:YES animated:YES];
currentSelection++;
}
else
{
[cell1 setSelected:YES animated:YES];
}*/
// NSIndexPath *indexPath1 = [homeTable indexPathForCell:cell];
NSLog(#"current===>%d",currentSelection);
//[cell1 setSelected:NO animated:YES];
//if(currentSelection == indexPath)
//UIButton *clickButton = (UIButton *)sender;
// NSIndexPath *indexPathHighlight = [NSIndexPath indexPathForRow:button.tag inSection:0];
//button.tag = indexPathHighlight.row;
//UITableViewCell *newCell = [homeTable cellForRowAtIndexPath:indexPathHighlight];
//if(newCell.selected == NO)
//{
//[newCell setSelected:YES animated:YES];
// [newCell setBackgroundColor:[UIColor lightGrayColor]];
//}
//else
// {
//[newCell setSelected:NO animated:YES];
//[newCell setBackgroundColor:[UIColor colorWithRed:232.0f/255.0f green:237.0f/255.0f blue:240.0f/255.0f alpha:1.0f]];
//}
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
MyCustomCell *cell1 = (MyCustomCell *)[homeTable cellForRowAtIndexPath:indexPath];
cell1.selectionStyle= UITableViewCellSelectionStyleBlue;
}
You can look at my messy button action method. I have tried many options but with no success. Please help on this.

Uncomment the line :
btn.tag = indexPath.row+1000;
Also change the cell selection style as
[cell setSelectionStyle:UITableViewCellSelectionStyleBlue];
when create it.
In SelectButtonTapped method :
- (void)SelectButtonTapped:(UIButton *)button
{
int buttonIndex = button.tag;
for (int row = 0; row<numberOfRows; row++)
{
NSIndexPath indexPathHighlight = [NSIndexPath indexPathForRow:row inSection:0];
UITableViewCell *newCell = [yourTable cellForRowAtIndexPath:indexPathHighlight];
if (row == buttonIndex - 1000)
{
[newCell setSelected:YES animated:YES];
}
else
{
[newCell setSelected:NO animated:YES];
}
}
}

Lets think that your table has only one section and tag of your button be the row number of the corresponding cell.
In the button action
int rownumber = button.tag;
//print the rownumber and see if you are getting the correct value
UITableViewCell *cell = [tablename cellForRowAtIndexPath:[NSIndexPath
indexPathForRow:rownumber inSection:0]];
[cell setHighlighted:YES];

Try this -
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
MyCustomCell *cell1 = (MyCustomCell *)[homeTable cellForRowAtIndexPath:indexPath];
cell1.selectionStyle= UITableViewCellSelectionStyleBlue;
}

Related

Managing multiple textview inside tableview

i have a tableview which required three textview for description. i have made a prototype cell containing text view with tag 1000.
i want to reuse this textview but the text of the textview changes when i scroll.
Some time Faraz take position of haider textview and sometime zaidi take position of faraz.
i try to give them unique tag also but still it doesnot help me.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *cellViewIdentifier = nil;
long section = indexPath.section;
UITableViewCell *cell;
if(section == kSocialStatusSection) {
if(indexPath.row < socialResult.socialStatus.count){
cellViewIdentifier = kCheckBoxItemCellViewIdentifier;
cellViewIdentifier = [cellViewIdentifier stringByAppendingString:langAppendString];
cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:cellViewIdentifier];
[cell setBackgroundColor:[UIColor clearColor]];
SocialStatus * socialStatus = [socialResult.socialStatus objectAtIndex:indexPath.row];
[cell setBackgroundColor:[UIColor clearColor]];
UILabel *titleLabel = (UILabel *) [cell viewWithTag:kTagTitleCellLabel];
// NSMutableDictionary *obj = [socialStatusArray objectAtIndex:indexPath.row];
[titleLabel setText:[LanguageUtilities isEnglishLanguage]?socialStatus.typeNameEn:socialStatus.typeNameAr];
UIButton *checkBox = (UIButton *) [cell viewWithTag:kTagCheckButton];
// checkBox.selected = NO;
if([socialStatus.selected boolValue]) {
checkBox.selected = YES;
}
else{
checkBox.selected = NO;
}
} else {
cellViewIdentifier = kDescriptionCellViewIdentifier;
cellViewIdentifier = [cellViewIdentifier stringByAppendingString:langAppendString];
cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:cellViewIdentifier];
[cell setBackgroundColor:[UIColor clearColor]];
GCPlaceholderTextView *textArea = (GCPlaceholderTextView *)[cell viewWithTag:kTagDescriptionTextArea];
textArea.placeholder =getLocalizedString(#"Description");
textArea.delegate = self;
textArea.text = #"FARAZ";
}
}
else if(section == kSocialStatusProblems){
if(indexPath.row < socialResult.socialProblems.count){
cellViewIdentifier = kCheckBoxItemCellViewIdentifier;
cellViewIdentifier = [cellViewIdentifier stringByAppendingString:langAppendString];
cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:cellViewIdentifier];
[cell setBackgroundColor:[UIColor clearColor]];
SocialProblem * socialProblem = [socialResult.socialProblems objectAtIndex:indexPath.row];
UILabel *titleLabel = (UILabel *) [cell viewWithTag:kTagTitleCellLabel];
// NSMutableDictionary *obj = [socialProblemsArray objectAtIndex:indexPath.row];
[titleLabel setText:[LanguageUtilities isEnglishLanguage]?socialProblem.typeNameEn:socialProblem.typeNameAr];
UIButton *checkBox = (UIButton *) [cell viewWithTag:kTagCheckButton];
if([socialProblem.selected boolValue]) {
checkBox.selected = YES;
}else{
checkBox.selected = NO;
}
} else {
cellViewIdentifier = kDescriptionCellViewIdentifier;
cellViewIdentifier = [cellViewIdentifier stringByAppendingString:langAppendString];
cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:cellViewIdentifier];
[cell setBackgroundColor:[UIColor clearColor]];
GCPlaceholderTextView *textArea = (GCPlaceholderTextView *)[cell viewWithTag:kTagDescriptionTextArea];
textArea.placeholder =getLocalizedString(#"Description");
textArea.delegate = self;
textArea.text = #"Haider";
}
}
else if(section == kProblemTypesSection){
if(indexPath.row < socialResult.socialProblemsTypes.count){
cellViewIdentifier = kCheckBoxItemCellViewIdentifier;
cellViewIdentifier = [cellViewIdentifier stringByAppendingString:langAppendString];
cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:cellViewIdentifier];
[cell setBackgroundColor:[UIColor clearColor]];
SocialProblemsType * socialProblemType = [socialResult.socialProblemsTypes objectAtIndex:indexPath.row];
UILabel *titleLabel = (UILabel *) [cell viewWithTag:kTagTitleCellLabel];
// NSMutableDictionary *obj = [problemTypeArray objectAtIndex:indexPath.row];
[titleLabel setText:[LanguageUtilities isEnglishLanguage]?socialProblemType.typeNameEn:socialProblemType.typeNameAr];
UIButton *checkBox = (UIButton *) [cell viewWithTag:kTagCheckButton];
if([socialProblemType.selected boolValue]) {
checkBox.selected = YES;
}else
{
checkBox.selected = NO;
}
} else {
cellViewIdentifier = kDescriptionCellViewIdentifier;
cellViewIdentifier = [cellViewIdentifier stringByAppendingString:langAppendString];
cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:cellViewIdentifier];
[cell setBackgroundColor:[UIColor clearColor]];
GCPlaceholderTextView * textArea= (GCPlaceholderTextView *)[cell viewWithTag:problemTypeTextViewTag];;
if (textArea != nil) {
textArea= (GCPlaceholderTextView *)[cell viewWithTag:problemTypeTextViewTag];
}else
{
textArea= (GCPlaceholderTextView *)[cell viewWithTag:kTagDescriptionTextArea];
[textArea setTag:problemTypeTextViewTag];
}
textArea.placeholder =getLocalizedString(#"Description");
textArea.delegate = self;
textArea.text = #"zaidi";
}
}
return cell;}
We can make do with an NSMutableArray object containing strings for each cell. You will have to fill the array with empty strings and use this info to fill the text field. It will be something like,
textView.text = [textViewStringsArr objectAtIndex:indexPath.row];
Since you're doing it programmatically within the view controller, you will have to set the view controller as your text view delegate. You can do
-(void)textViewDidEndEditing:(UITextView *)textView {
UITableViewCell *cell = (UITableViewCell*)textField.superview;
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
... Since you've the index path, you can map it to an array.
[textViewStringsArr replaceObjectAtIndexPath:indexPath withObject:textView.text];
}
This would be the basic idea. Start with a mutable array of empty strings and modify them every time the text view is updated by replacing the original text with the new text. Hope this helps.

UITableView Add button on new cell

Im trying to add a button into a new cell in a tableview, for example, I need a button under cell '1' if dim is not 0.
However I'm unable to do it. Please enlighten me.
- (void)viewDidLoad
{
[super viewDidLoad];
_displaynum = [NSArray arrayWithObjects:#"1",#"2",#"3", nil];
_displayID = [NSArray arrayWithObjects:#"ID = 1",#"ID = 2",#"ID = 3", nil];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [_displaynum count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *lightIdentifier = #"lightIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:lightIdentifier];
if (cell == nil){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:lightIdentifier];
}
UISwitch *switchLights = [[UISwitch alloc] initWithFrame:CGRectMake(1.0, 1.0, 20.0, 20.0)];
cell.textLabel.text = [_displayLights objectAtIndex:indexPath.row];
cell.detailTextLabel.text =[_displayLightsID objectAtIndex:indexPath.row];
cell.accessoryView = switchLights;
switchLights.on = NO;
int dim = 1;
if ((dim =! 0)) {
NSArray *insertIndexPaths = [NSArray arrayWithObjects:
[NSIndexPath indexPathForRow:1 inSection:0],
nil];
NSArray *deleteIndexPaths = [NSArray arrayWithObjects:
[NSIndexPath indexPathForRow:2 inSection:0],nil];
[tableView beginUpdates];
[tableView insertRowsAtIndexPaths:insertIndexPaths withRowAnimation:UITableViewRowAnimationRight];
[tableView deleteRowsAtIndexPaths:deleteIndexPaths withRowAnimation:UITableViewRowAnimationFade];
[tableView endUpdates];
}
return cell;
}
}
First of all, cellForRowAtIndexPath: is not the right place to insert or delete rows the way you are doing.
cellForRowAtIndexPath: gets called every time a new cell is drawn by iOS. So, this is the place where you can modify your cells and simply return it.
That said, this is what you need to do:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *lightIdentifier = #"lightIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:lightIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:lightIdentifier];
}
int dim = 1;
if (dim != 0 && indexPath.row == 1) {
CGRect buttonRect = CGRectMake(210, 25, 65, 25);
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame = buttonRect;
// set the button title here if it will always be the same
[button setTitle:#"Action" forState:UIControlStateNormal];
button.tag = 1;
[button addTarget:self action:#selector(myAction:) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:button];
}
return cell;
}

How to load NSArray in steps on UITableView

-(void)addMyButton
{
button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button addTarget:self action:#selector(aMethod) forControlEvents:UIControlEventTouchUpInside];
button.tag = 1;
[button setTitle:#"Show More" forState:UIControlStateNormal];
button.frame = CGRectMake(110.0, 430.0, 100.0, 40.0);
[self.view addSubview:button];
}
-(void)viewDidLoad
{
[self addMyButton]; // Call add button method on view load
n=1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if(n==1){
n++;
return 10;
}
else if(n==2){
n++;
return 20;
}
else
return 30;
}
-(void) aMethod
{
if(n>=3)
{
[button setTitle:#"Return" forState:UIControlStateNormal];
[button setTitleColor:[UIColor greenColor] forState:UIControlStateNormal];
//[button setBackgroundColor:[UIColor brownColor]];
}
else{
// [button setTitle:#"Show More" forState:UIControlStateNormal];
// [button setBackgroundColor:[UIColor clearColor]];
}
NSLog(#"n==>> %d",n);
[tbl reloadData];
}
An array having thirty elements when i click ok return button then it should be shows twenty elements on TableView after next clicked i should shows ten elements and so on..
Please try the edited code
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if(n==1)
{
n++;
return 20; //edited from return 10 to return 20-- to return 20 elements for the first time
}
else if (n==2)
{
return 30; //Return 30 when click on view more
}
}
-(void) aMethod
{
if(n==2)
{
[button setTitle:#"Return" forState:UIControlStateNormal];
[button setTitleColor:[UIColor greenColor] forState:UIControlStateNormal];
//[button setBackgroundColor:[UIColor brownColor]];
}
else
{
n=1;
[button setTitle:#"Show More" forState:UIControlStateNormal];
[button setBackgroundColor:[UIColor clearColor]];
}
NSLog(#"n==>> %d",n);
[tbl reloadData];
}
try my code and let me know if i miss anything according to your requirement
try like this....
#import "YourTableViewControllerClass.h"
#interface YourTableViewControllerClass ()
{
NSMutableArray * tableArray;
}
#end
#implementation TableViewController
- (void)viewDidLoad
{
[super viewDidLoad];
tableArray = [[NSMutableArray alloc]initWithArray:#[#"1",#"2",#"3",#"4",#"5",#"6",#"7",#"8",#"9",#"10"]];
}
-(IBAction)addMoreCells // button action to add more cells
{
[tableArray addObjectsFromArray:#[#"11",#"12",#"13",#"14",#"15",#"16",#"17",#"18",#"19",#"20"]];
[self.tableView reloadData];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
return tableArray.count ;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"cell"];
}
cell.textLabel.text = [tableArray objectAtIndex:indexPath.row];
return cell;
}
#end
It looks like you're almost there.
You need tableView:cellForRowAtIndexPath: from the UITableViewDataSource protocol. This method effectively links the correct index in your array to a UITableViewCell.
e.g. something like:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"myCell"];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"myCell"];
}
cell.textLabel.text = [self.myArray objectAtIndex:indexPath.row];
return cell;
}
Try this,
-(void)addMyButton
{
button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button addTarget:self action:#selector(aMethod)forControlEvents:UIControlEventTouchUpInside];
button.tag = 1;
[button setTitle:#"Show More" forState:UIControlStateNormal];
button.frame = CGRectMake(110.0, 430.0, 100.0, 40.0);
[self.view addSubview:button];
}
-(void)viewDidLoad
{
[super viewDidLoad];
[self addMyButton]; // Call add button method on view load
n=2;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if( [your_array count] <= (n*10)){
n=1;
return [your_array count];
}
else
{
return n*10;
}
return 0;
}
-(void)aMethod
{
n++;
if([your_array count]<=n*10){
[button setTitle:#"Return" forState:UIControlStateNormal];
[button setTitleColor:[UIColor greenColor] forState:UIControlStateNormal];
}
else{
[button setTitle:#"Show More" forState:UIControlStateNormal];
[button setBackgroundColor:[UIColor clearColor]];
}
[tbl reloadData];
}
Also add the code to set the data in table view cell (from your array) inside this method,
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
You can check the functionality by using the dummy code given below,
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleTableItem";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
cell.textLabel.text = [NSString stringWithFormat:#"%ld",indexPath.row+1];
return cell;
}

UIButton subview in UITableViewCell doesn't hide as expected

My recent frustration is a UIButton subview in each UITableViewCell of my UITableView which I want to setHidden: according to a specific clause for each indexPath. My code is pretty much the following:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
...
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
[self initCell:cell forIndexPath:indexPath];
}
[self updateCell:cell forIndexPath:indexPath];
return cell;
}
and the init and update methods are the following:
- (void)initCell:(UITableViewCell *)cell forIndexPath:(NSIndexPath *)indexPath
{
...
UIButton *btnMy = [UIButton buttonWithType:UIButtonTypeCustom];
btnMy.tag = kButtonMyTag;
[btnMy setFrame:CGRectMake(170, 45, 100, 30)];
[btnMy setBackgroundImage:[UIImage imageNamed:#"btn_image"] forState:UIControlStateNormal];
btnMy.adjustsImageWhenHighlighted = YES;
[btnMy setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
btnMy.titleLabel.font = [UIFont fontWithName:#"MyFont" size:14];
[btnMy addTarget:self action:#selector(btnMyPressed:) forControlEvents:UIControlEventTouchUpInside];
[cell addSubview:btnMy];
UIImageView *imgViewAccessory = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"table_accessory"]];
cell.accessoryView = imgViewAccessory;
[imgViewAccessory release];
}
- (void)updateCell:(UITableViewCell *)cell forIndexPath:(NSIndexPath *)indexPath
{
UIButton *btnMy = (UIButton *)[cell viewWithTag:kButtonMyTag];
MyObject *object = (MyObject *)[self.dataSource objectAtIndex:indexPath.row];
if(object.meetsCondition)
{
btnMy.hidden = NO;
}
else
{
btnMy.hidden = YES;
}
...
}
The frustrating result is that when scrolling the button shows and hides randomly and not as expected according the if clause in the updateCell method.
Any help would be much appreciated. Thanks in advance!
You should make custom cell and depending upon the condition show and hide the button
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSArray *nib;
static NSString *cellIdentifier= #"cell";
UITableViewCell *theCell = [self.tblView dequeueReusableCellWithIdentifier:cellIdentifier];
if([theCell.contentView subviews]){
for(UIView *view in [theCell.contentView subviews]){
[view removeFromSuperview];
}
}
if(theCell== nil)
{
nib = [[NSBundle mainBundle] loadNibNamed:#"Your custom cell name" owner:self options:nil];
theCell = [nib objectAtIndex:0];
theCell.selectionStyle = UITableViewCellSelectionStyleNone;
}
UIButton *btn=(UIButton*)[theCell.contentView viewWithTag:101];
if(yourcondition)
//hide button
else
//show button
}
This will do
Use this code in your CellForRowAtIndexPath Also.
MyObject *object = (MyObject *)[self.dataSource objectAtIndex:indexPath.row];
if(object.meetsCondition) {
btnMy.hidden = NO;
}
else {
btnMy.hidden = YES;
}

CoreData with a CheckBox in a UITableViewCell

im trying to implement a tableview with a checkbox on each cell in wish the status(Checked/Unchecked) will get saved on a CoreData data base. i still had no success with the current implementation. If i could get some help i would be very Thankful.
The code in question:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [pictureListData count];
}
- (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];
}
// Get the core data object we need to use to populate this table cell
Compras *currentCell = [pictureListData objectAtIndex:indexPath.row];
BOOL checked = currentCell.status;
UIImage *image = (checked) ? [UIImage imageNamed:#"cb_mono_on#2x.png"] : [UIImage imageNamed:#"cb_mono_off#2x.png"];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
CGRect frame = CGRectMake(0.0, 0.0, image.size.width, image.size.height);
button.frame = frame; // match the button's size with the image size
[button setBackgroundImage:image forState:UIControlStateNormal];
// set the button's target to this table view controller so we can interpret touch events and map that to a NSIndexSet
[button addTarget:self action:#selector(checkButtonTapped:event:) forControlEvents:UIControlEventTouchUpInside];
cell.backgroundColor = [UIColor clearColor];
cell.accessoryView = button;
return cell;
}
- (void)checkButtonTapped:(id)sender event:(id)event
{
NSSet *touches = [event allTouches];
UITouch *touch = [touches anyObject];
CGPoint currentTouchPosition = [touch locationInView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint: currentTouchPosition];
if (indexPath != nil)
{
[self tableView: self.tableView accessoryButtonTappedForRowWithIndexPath: indexPath];
}
}
- (void) tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath {
Compras *currentCell = [pictureListData objectAtIndex:indexPath.row];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
UIButton *button = (UIButton *)cell.accessoryView;
UIImage *image = [UIImage imageNamed:#"cb_mono_on#2x.png"];
// patient.check is a string value set to either "Y" or "N"
// This allows the check mark to be permanently saved
if (currentCell.status) {
image = [UIImage imageNamed:#"cb_mono_off#2x.png"];
currentCell.status = NO;
}
else {
// image defaults to checked.png
image = [UIImage imageNamed:#"cb_mono_on#2x.png"];
currentCell.status = YES;
}
[button setBackgroundImage:image forState:UIControlStateNormal];
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete)
{
// Get a reference to the table item in our data array
Compras *itemToDelete = [self.pictureListData objectAtIndex:indexPath.row];
// Delete the item in Core Data
[self.managedObjectContext deleteObject:itemToDelete];
// Remove the item from our array
[pictureListData removeObjectAtIndex:indexPath.row];
// Commit the deletion in core data
NSError *error;
if (![self.managedObjectContext save:&error])
NSLog(#"Failed to delete picture item with error: %#", [error domain]);
// Delete the row from the data source
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
}
You wrote in a comment, that currentCell is a NSManagedObject.
As CoreData only can deal with objects, bool values are wrapped with in an instance of NSNumber
BOOL checked = [currentCell.status boolValue];
your code will always result in YES, as you are writing the object's address to the BOOL. and it will most likely never be 0.