I have insert 2 section and 2 rows in tableview, then i tried to get selected section and row value using UITapGestureRecognizer, but i have to get only indexPath.section value, i want both section and row value. Is it possible to do that? please help me
Thanks in Advance
I tried this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell=[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"Cell"];
cell.selectionStyle = UITableViewCellSelectionStyleGray;
// Add the PatientName Label
UILabel *cellTitle=[[UILabel alloc]initWithFrame:CGRectMake(100, 7, 300, 30)];
cellTitle.userInteractionEnabled = YES;
cellTitle.tag = indexPath.section;
[cellTitle setBackgroundColor:[UIColor clearColor]];
[cellTitle setFont:[UIFont fontWithName:#"Helvetica" size:14]];
[cellTitle setText:[[cellArray objectAtIndex:indexPath.section] objectAtIndex:indexPath.row]];
[cell.contentView addSubview:cellTitle];
UITapGestureRecognizer *labelTap = [[UITapGestureRecognizer alloc] init];
[labelTap addTarget:self action:#selector(viewPatient:)];
[labelTap setDelegate:nil];
[labelTap setNumberOfTapsRequired:1];
[cellTitle addGestureRecognizer:labelTap]; // cellTitle add here
[labelTap release];
}
-(void)viewPatient:(id)sender
{
UITapGestureRecognizer *lSender = sender;
UILabel *lObjLabel = (UILabel *)[lSender view];
NSLog(#"tag:%d",lObjLabel.tag); // only get indexpath.section value
}
Use this code..
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:[sender tag] inSection:
[[sender superview] tag]];
write this line..
[cellTitle setText:[[cellArray objectAtIndex:indexPath.row] objectAtIndex:indexPath.section]];
instead of
[cellTitle setText:[[cellArray objectAtIndex:indexPath.section] objectAtIndex:indexPath.row]];
Related
I have to make a call to specific number when imageview is clicked in tableviewcell.The number to which call is made is displayed in a label beside the imageview.But I couldn't get which cell is clicked.Always its referring to the last cell.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(cell == nil)
{
cell =[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
lblphone = [[UILabel alloc] initWithFrame:CGRectZero];
lblphone.tag = 116;
lblphone.backgroundColor = [UIColor clearColor];
[lblphone setFont:[UIFont fontWithName:#"Helvetica" size:12]];
[lblphone setLineBreakMode:UILineBreakModeWordWrap];
[lblphone setUserInteractionEnabled:YES];
UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(labelButton:)];
tapGestureRecognizer.cancelsTouchesInView=NO;
[tapGestureRecognizer setNumberOfTapsRequired:1];
[lblphone addGestureRecognizer:tapGestureRecognizer];
[tapGestureRecognizer release];
[cell addSubview:lblphone];
myImageView = [[UIImageView alloc] initWithFrame:CGRectZero];
myImageView.tag = 120;
myImageView.image=[UIImage imageNamed:#"CallImg.png"];
UITapGestureRecognizer *tapped = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(imageSelectedInTable:)];
[tapped setNumberOfTapsRequired:1];
[myImageView addGestureRecognizer:tapped];
[tapped release];
[cell addSubview:myImageView];
}
[myImageView setFrame:CGRectMake(10, 50,30,30)];
myImageView= (UIImageView*)[cell viewWithTag:120];
myImageView.image=[UIImage imageNamed:#"CallImg.png"];
myImageView.userInteractionEnabled=YES;
CGSize constraint5 = CGSizeMake(320, 2000.0f);
CGSize size5=[phone sizeWithFont:[UIFont fontWithName:#"Helvetica" size:14] constrainedToSize:constraint5 lineBreakMode:UILineBreakModeWordWrap];
lblphone =(UILabel *)[cell viewWithTag:116];
[lblphone setFrame:CGRectMake(45,name.frame.size.height+name.frame.origin.y,320, size5.height)];
lblphone.textAlignment=UITextAlignmentLeft;
lblphone.backgroundColor=[UIColor clearColor];
lblphone.text=[NSString stringWithFormat:#"%# ",phone ];
[lblphone sizeToFit];
}
And in the tapgesture of imageclick I am writing this :
-(IBAction)imageSelectedInTable:(UITapGestureRecognizer*)gesture
{
UIImageView *imgView = (UIImageView *) [gesture view];
UITableViewCell *cell = (UITableViewCell*)[[imgView superview]superview];
NSIndexPath *tappedIndexPath = [self.tableView indexPathForCell:cell];
NSLog(#"Image Tap %#", tappedIndexPath);
UILabel *phoneno = (UILabel *)[cell viewWithTag:116];
NSString *phoneNumber = [#"telprompt://" stringByAppendingString:phoneno.text];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:phoneNumber]];
}
But it is always referncing to the last cell clicked irrespective of which cell is clicked.Couldn't understand where im going wrong ?
I see you try to access your cell,
UITableViewCell *cell = (UITableViewCell*)[[imgView superview]superview];
but you add your image view to
[cell addSubview:myImageView];
You should be adding your image view to cell.contentView.
It looks like the image view is a subview of the cell (one step down the tree), and the code that's probing for the parent is taking two steps up ...superview superview. (That latter approach is right for nib defined cells which add subviews to the cell's contentView).
Here's a safer way to climb the view hierarchy that will work no matter how the cell was built.
- (UITableViewCell *)tableViewCellContaining:(UIView *)aView {
UIView *answer = aView;
while (answer && ![answer isKindOfClass:[UITableViewCell self]])
answer = answer.superview;
return answer;
}
I think your code will probably work if you replace this line:
UITableViewCell *cell = (UITableViewCell*)[[imgView superview]superview];
with this line
UITableViewCell *cell = [self tableViewCellContaining:imgView]
for get/know Which cell is clicked, Write Following code
UITableViewCell *cell = (UITableViewCell *)[[imgView superview]superview];
and if you alSo want to get indexPath of tapped cell then write
NSIndexPath *indexPath = [tableView indexPathForCell:cell];
EDITED :-> Another way is
Give tag of UIImageView in cellForRowAtIndexPath Method
Such like,
imageView.tag = indexPath.row;
And Use Following Code
int row = ((UIImageView*)imgView).tag; //Or// int row = ((UIGestureRecognizer *)sender).view.tag;
NSIndexPath* indexpath = [NSIndexPath indexPathForRow:row inSection:0];
UITableViewCell* cell = [table cellForRowAtIndexPath:indexPath];
Here You can get Cell of Tapped UIImageView.
I have seen some posts before, but didn't get the answer yet, thats why i am trying to post again in more effective manner. How can i use check-uncheck functionality in UITableView like below image.
This is table i want when i click on button of any cell, that buttons image will change, not on all cells.
For Check-Uncheck functionality only buttonClicked: method is not enough. You will have also put the condition in cellForRowAtIndexPath: method for which button is selected or which in unselected because cellForRowAtIndexPath: method will call each time when you will scroll your UITableView and cells will be refresh.
And i saw your previous question you're adding two buttons with two action not a good way just change the image of button for check-uncheck.
So here is what i do for this -
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController<UITableViewDelegate, UITableViewDataSource>
{
IBOutlet UITableView *tblView;
NSMutableArray *arrayCheckUnchek; // Will handle which button is selected or which is unselected
NSMutableArray *cellDataArray; // this is your data array
}
#end
Now in ViewController.m class -
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
arrayCheckUnchek = [[NSMutableArray alloc]init];
//Assign your cell data array
cellDataArray = [[NSMutableArray alloc]initWithObjects:#"cell-1",#"cell-2",#"cell-3",#"cell-4",#"cell-5", nil];
// setting all unchecks initially
for(int i=0; i<[cellDataArray count]; i++)
{
[arrayCheckUnchek addObject:#"Uncheck"];
}
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [cellDataArray 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];
}
cell.textLabel.text = [cellDataArray objectAtIndex:indexPath.row];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setFrame:CGRectMake(270.0, 7.0, 30.0, 30.0)];
if([[arrayCheckUnchek objectAtIndex:indexPath.row] isEqualToString:#"Uncheck"])
[button setImage:[UIImage imageNamed:#"uncheck_icon"] forState:UIControlStateNormal];
else
[button setImage:[UIImage imageNamed:#"check_icon"] forState:UIControlStateNormal];
[button addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:button];
return cell;
}
-(void)buttonClicked:(id)sender
{
//Getting the indexPath of cell of clicked button
CGPoint touchPoint = [sender convertPoint:CGPointZero toView:tblView];
NSIndexPath *indexPath = [tblView indexPathForRowAtPoint:touchPoint];
// No need to use tag sender will keep the reference of clicked button
UIButton *button = (UIButton *)sender;
//Checking the condition button is checked or unchecked.
//accordingly replace the array object and change the button image
if([[arrayCheckUnchek objectAtIndex:indexPath.row] isEqualToString:#"Uncheck"])
{
[button setImage:[UIImage imageNamed:#"check_icon"] forState:UIControlStateNormal];
[arrayCheckUnchek replaceObjectAtIndex:indexPath.row withObject:#"Check"];
}
else
{
[button setImage:[UIImage imageNamed:#"uncheck_icon"] forState:UIControlStateNormal];
[arrayCheckUnchek replaceObjectAtIndex:indexPath.row withObject:#"Uncheck"];
}
}
And finally it will look like -
Tags are useful with customised uitableviewcell designed in IB. If you create cells programmatically, you don't need tags. You use them only to find correct uiview to set properties.
Yes this is simple to set Tags while declaring the classes inside UITableViewCell and identify them using tags. I have posted some sample code for your reference. Am not sure it will solve your problem. You asked how to set tags and identify the classes using tags. So it will give you some basic idea about your question.
-(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] autorelease];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
label1 = [[UIView alloc] initWithFrame:CGRectMake(2, 20, 15, 15)];
label1.tag = 100;
label1.backgroundColor = [UIColor whiteColor];
label1.layer.cornerRadius = 5;
[cell.contentView addSubview: label1];
label2 = [[UILabel alloc] initWithFrame:CGRectMake(25, 2, 165, 23)];
label2.tag = 101;
label2.font = [UIFont boldSystemFontOfSize:15];
label2.backgroundColor = [UIColor clearColor];
[cell.contentView addSubview: label2];
label3 = [[UILabel alloc] initWithFrame:CGRectMake(190, 2, 90, 23)];
label3.tag = 102;
label3.font = [UIFont systemFontOfSize:14];
label3.textColor = [UIColor colorWithRed:0.14117670588235 green:0.435294117647059 blue:0.847058823529412 alpha:1];
label3.backgroundColor = [UIColor clearColor];
label3.textAlignment = UITextAlignmentRight;
[cell.contentView addSubview: label3];
}
label1 = (UILabel *) [cell.contentView viewWithTag:100];
NSString *string1 = [array1 objectAtIndex:indexPath.row];
label2 = (UILabel *) [cell.contentView viewWithTag:101];
NSString * string2 = [array2 objectAtIndex:indexPath.row];
label3 = (UILabel *) [cell.contentView viewWithTag:102];
NSString * string3 = [array3 objectAtIndex:indexPath.row];
return cell;
}
Please let me know this is useful or not. Otherwise we'll go to some other way.
Happy Coding. Thanks.
i agree with #VakulSaini because u can do this to handle which cell touch or swipe or what ever and this is an ex:
-(void)handleSwipLeft:(UISwipeGestureRecognizer *)gestureRecognizer
{
CGPoint Location = [gestureRecognizer locationInView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:Location];
cell = [tableView cellForRowAtIndexPath:indexPath];
}
Use cellForRowAtIndexPath method of UITableView and in This method Add any component like (UITextField,UILabel ..... etc ) In your UITableViewCell by using [cell.contentView addSubview:YourComponentName]; and give each component to its tag by indexPath.row.
such like ,,,
YourComponentName.tag = indexPath.row;
My UITableView is adding duplicate label on top of each other when I scroll up and down. So eventally so many labels get added that the add slows down and crash's.
- (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] autorelease];
}
UILabel *label;
label = [[UILabel alloc] initWithFrame:nameFrame];
[label setText:[name objectAtIndex:indexPath.row + indexPath.section]];
[label setFont:[UIFont fontWithName:#"Helvetica" size:18]];
[label setBackgroundColor:[UIColor clearColor]];
[cell addSubview:label];
[label release];
label = [[UILabel alloc] initWithFrame:statusFrame];
[label setText:[status objectAtIndex:indexPath.row + indexPath.section]];
[label setFont:[UIFont fontWithName:#"Helvetica" size:18]];
[label setBackgroundColor:[UIColor clearColor]];
[label setTextAlignment:(UITextAlignmentRight)];
[cell addSubview:label];
[label release];
return cell;
}
You are dequeuing reusable cells so the UILabel already exists on each dequeued cell. Try the following code.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UILabel *label;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
label = [[UILabel alloc] initWithFrame:nameFrame];
label.tag = 1; //Important for finding this label
[label setText:[name objectAtIndex:indexPath.row + indexPath.section]];
[label setFont:[UIFont fontWithName:#"Helvetica" size:18]];
[label setBackgroundColor:[UIColor clearColor]];
[cell.contentView addSubview:label];
[label release];
label = [[UILabel alloc] initWithFrame:statusFrame];
label.tag = 2; //Important for finding this label
[label setText:[status objectAtIndex:indexPath.row + indexPath.section]];
[label setFont:[UIFont fontWithName:#"Helvetica" size:18]];
[label setBackgroundColor:[UIColor clearColor]];
[label setTextAlignment:(UITextAlignmentRight)];
[cell.contentView addSubview:label];
[label release];
}
else
{
label = (UILabel*)[cell.contentView viewWithTag:1];
label.text = [name objectAtIndex:indexPath.row + indexPath.section];
label = (UILabel*)[cell.contentView viewWithTag:2];
label.text = [status objectAtIndex:indexPath.row + indexPath.section];
}
return cell;
}
I did adjust the code to use the cell's contentView.
You need to simply remove the subview:
for (UIView * view in cell.contentView.subviews)
{
[view removeFromSuperview];
view = nil;
}
This will do the work "I had the same issue"
The way I solved this was not very elegant but worked.
The problem, as mentioned by Joe is that we are reusing the cells by dequeuing them. This means that sometimes we use a cell which already has its properties previously set, eg its textLabel. In my case it was due to differences in the cell structure. It was overlapping the imageview from one cell over another which shouldn't have an image at all.
I found that identifying the problematic parts and setting them to nil at the start of cellForRowAtIndex fixed the problem. This is the equivalent of wiping your cell slate clean before reusing it.
Here is an edited version of mine:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell * cell = [self.tableView dequeueReusableCellWithIdentifier:bCellIdentifier];
cell.imageView.image = Nil;
cell.textLabel.text = Nil;
_nameField.text = #"";
...
// Setting the code with regards to the cells here
...
return cell;
}
Hope this helps
I have created a check box using the uiimageview and i have placed the checkbox into the uitableview cell like below
i want to get indexpath.row when i check the check box.
so i added the uiimageviiew inside the cell. so the didSelectRowAtIndexPath is gets called and gives me the indexpath.row.
but when the row is selected i want to show the detailed view.
now this runs me into trouble.
so can you people suggest me how to tackle my above problem.
when i check the checkbox i want to get the indexpath.row.
and when the row is selected i need to show the detailed view.
Thanks for your time and help
UPDATE 1 :
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
profileName = [appDelegate.archivedItemsList objectAtIndex:indexPath.row];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"xc"] autorelease];
cb = [[UIButton alloc] initWithFrame:CGRectMake(5,10, unselectedImage.size.width, unselectedImage.size.height)];
[cb setImage:unselectedImage forState:UIControlStateNormal];
[cb setImage:selectedImage forState:UIControlStateSelected];
[cb addTarget:self action:#selector(buttonAction:) forControlEvents:UIControlEventTouchDown];
[cell.contentView addSubview:cb];
}
if ( tableView == myTableView )
{
titleLabel = [[UILabel alloc]initWithFrame:CGRectMake(60, 0, 150, 35)];
titleLabel.font = [UIFont boldSystemFontOfSize:13];
titleLabel.textColor = [UIColor blackColor];
[cell.contentView addSubview:titleLabel];
NSString *subjectData = [profileName.archive_subject stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]];
[titleLabel setText:[NSString stringWithFormat: #"%# ", subjectData]];
lblDescription = [[UILabel alloc]initWithFrame:CGRectMake(60, 30, 210, 30)];
lblDescription.numberOfLines = 2;
lblDescription.lineBreakMode = YES;
lblDescription.adjustsFontSizeToFitWidth = YES;
lblDescription.font = [UIFont systemFontOfSize:10];
lblDescription.textColor = [UIColor grayColor];
[cell.contentView addSubview:lblDescription];
NSString *CompanyName = [profileName.archive_content stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]];
[lblDescription setText:[NSString stringWithFormat: #"%# ", CompanyName]];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
return cell;
}
Use a UIButton instead of UIImageView for your checkbox - this way you can add an action/method to it, where you can grab the indexPath, plus you can add different images for selected/unselected state which will eliminate all the confusing stuff happening in your code above:
So in your cellForRowAtIndexPath: method:
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
...// Your existing code here
UIImage *unselectedCheckboxImage = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"unselectedImageName" ofType:#"imageType"]];
UIImage *selectedCheckboxImage = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"selectedImageName" ofType:#"imageType"]];
UIButton *cb = [[UIButton alloc] initWithFrame:CGRectMake(desiredX, desiredY, unselectedCheckboxImage.frame.size.width, unselectedCheckboxImage.frame.size.height)];
[cb setImage:unselectedCheckboxImage forState:UIControlStateNormal];
[cb setImage:selectedCheckboxImage forState:UIControlStateSelected];
[cb addTarget:self action:#selector(buttonAction:) forControlEvents:UIControlEventTouchDown];
[cell.contentView addSubview:cb];
[cb release];
}
And then for your button action method:
- (IBAction)buttonAction:(id)sender
{
if ([sender isKindOfClass:[UIButton class]])
{
UIButton *checkboxButton = (UIButton*)sender;
checkboxButton.selected = !checkboxButton.selected;
NSIndexPath *indexPath = [self.myTableView indexPathForCell:(UITableViewCell*)[[checkboxButton superview] superview]];
// Do whatever you like here
}
}
I think your logic is causing the problem in the didSelectRowAtIndexPath: method; make sure that's right. Besides, if you just want to use check mark for the cell I think it's better if you use UITableViewCellAccessoryCheckmark. This may give you a basic idea.
This is my cellForRowAtIndexPath function. I could not get the setText to the label to work. Can you please help me out?
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UILabel *messageLabel = nil;
int row = [indexPath row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithFrame:CGRectMake(0, 0, 320, ROWHEIGHT) reuseIdentifier:CellIdentifier];
messageLabel = [[UILabel alloc] initWithFrame:CGRectMake(60, 5, 240, 60)];
[messageLabel setFont:[UIFont fontWithName:#"ArialMT" size:12]];
[messageLabel setTextColor:[UIColor blackColor]];
[messageLabel setBackgroundColor:[UIColor clearColor]];
[messageLabel setNumberOfLines:3];
[messageLabel setLineBreakMode:UILineBreakModeWordWrap];
[messageLabel setTag: messageTag];
[cell.contentView addSubview:messageLabel];
}
else{
messageLabel = (UILabel *)[cell viewWithTag:messageTag];
}
[messageLabel setText:[[[aSingleton wallItemArray] objectAtIndex:row] message]];
NSLog(#" -- > at row %d, message: %#", row, [[[aSingleton wallItemArray] objectAtIndex:row] message]);
return cell;
}
You're adding the UILabel to the cell's contentView, but asking the cell for the view.
Have you tried:
messageLabel = (UILabel *)[cell.contentView viewWithTag:messageTag];
EDIT: Also, you have two memory leaks - you're alloc'ing a UITableViewCell and a UILabel without (auto)releasing them anywhere.