UITableViewCell detailTextLabel area not allowing selection of cell - ios

Inside a UITableViewCell, the area covered by detailTextLabel doesn't recognise selection of the cell.
The cell style is UITableViewCellStyleSubtitle
The entire bottom area of the cell is not selectable and users are sometimes tapping the cell multiple times before tapping high enough on the cell for it to detect the touch.
I've tried [[myCell detailTextLabel] setUserInteractionEnabled:NO] or setting background colour to clear which has helped in similar cases, what else can I do?
I thought about adding a UILabel as a subview of the cell instead of detailTextLabel which I will try if I can't find the answer here.
EDIT - as requested
Here is the code from cellForRowAtIndexPath
NSString *cellId = #"cell";
locationsCell = [tableView dequeueReusableCellWithIdentifier:cellId];
if(locationsCell == nil) {
locationsCell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellId];
}
[[locationsCell textLabel] setFont:[UIFont fontWithName:#"Optima-Bold" size:18]];
[[locationsCell textLabel] setText:#"Choose your location"];
[[locationsCell detailTextLabel] setFont:[UIFont fontWithName:#"Optima" size:14]];
[[locationsCell detailTextLabel] setText:#"Tap to select"];
[[locationsCell detailTextLabel] setBackgroundColor:[UIColor clearColor]];
return locationsCell;
EDIT
Sorry I've messed up. I had set a footer view for another table and it has added a clear footer view that made the cell un-selectable instead of adding a conditional for the two tables. I removed the footer and it's working.

Friend I tried myself what you are saying but for me it is working.
I tried simple code like this,
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *TableIdentifier = #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:TableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:TableIdentifier];
}
cell.textLabel.text = [array objectAtIndex:indexPath.row];
cell.detailTextLabel.text=[NSString stringWithFormat:#"subtitle area text working %# %d",[array objectAtIndex:indexPath.row],indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"indexpath row %d",indexPath.row);
UIAlertView *alert=[[UIAlertView alloc]initWithTitle:#"working" message:#"yes" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
}

Related

UITableView change image on cell select and reset others

I'd like to change a UIImage which is inside a UITableViewCell when the user selects the row. Thats now too dificult. I can do this in didSelectRowAtIndex just fine. However, and heres the problem, I want the other cells (each cell has standard image) to have the standard image again. (If the cells have the standard image again, the selected image should be "marked" (meaning the non-marked image will be replaced by the marked image, which I already have the code for)
See it as a Checkbox that you know from HTML.
Here is my attempt:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView cellForRowAtIndexPath:indexPath];
[tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:YES];
//Little flashing animation
[tableView deselectRowAtIndexPath:indexPath animated:YES];
[UIView animateWithDuration:2.0f animations:^{
} completion:^(BOOL finished) {
;
}];
//Mark the selected cell
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
ALog(#"%i", cell.imageView.tag);
ALog(#"%i", [[[tableView cellForRowAtIndexPath:indexPath] imageView] tag]);
UIImageView *iconimgView = (UIImageView *)[[tableView cellForRowAtIndexPath:indexPath] viewWithTag:TAG_IMAGEMARKERCELL];
[iconimgView setImage:[UIImage imageNamed:#"circle-answer-marked.png"]];
//..
}
The UIImageView is defined here:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
//Add this to cell only once, not everytime a cell is displayed! (Everyhing goes in here)
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
[[cell textLabel] setNumberOfLines:0]; // unlimited number of lines
[[cell textLabel] setLineBreakMode:NSLineBreakByWordWrapping];
[[cell textLabel] setFont:[UIFont fontWithName:#"PTSans-Regular" size:33 / 2]];
[[cell textLabel] setTextColor:[self colorFromHexString:COLOR_DEFAULT_TEXT_COLOR]];
cell.indentationLevel = cell.indentationLevel + 2;
// //Marker image
imgCell_Marker = [[UIImageView alloc]initWithFrame:CGRectMake(10, 22, 20, 20)];
imgCell_Marker.image=[UIImage imageNamed:#"circle-answer.png"];
imgCell_Marker.tag = TAG_IMAGEMARKERCELL;
ALog(#"%#", imgCell_Marker);
[cell.contentView addSubview:imgCell_Marker];
}
//..
return cell;
}
Odd thing is, the UIImageViews have a predefined tag but if I want to get my hands on that in the didSelectRowAtIndexPath its always "0". (the default value of the tag)
Thanks in advance.
Use this block of code:
-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView reloadData];
UITableViewCell *cell = (UITableViewCell *)[tableView cellForRowAtIndexPath:indexPath];
cell.imageView.image = [UIImage imageNamed:#"image.png"];
}
At first, you set all of your cells to their default condition, and then you change the image of your current cell.
You have issues on a number of fronts.
First, the information which determines what image should be displayed should be part of your model. So, when a row is selected, set a flag in your model to say that this item is tagged. At the same time, find the other items that are tagged and untag them. Now, reload the rows that have changed. In cellForRowAtIndexPath, update the requested cells to set the standard or the alternative image based on the tag info from the model.
Second, for your use of tag - you are getting mixed up between imgCell_Marker and imageView. When you do:
ALog(#"%i", [[[tableView cellForRowAtIndexPath:indexPath] imageView] tag]);
you are querying the default imageView, so the tag will always be zero. You should be using viewWithTag:TAG_IMAGEMARKERCELL to find the actual image view you want.
From attribute inspector, set accessory as "Check Mark" for your prototypeCell. This would solve your issue. No need to change image or anything. let me know if this is not what you want
Make you life easy. Use UITableViewCell::selectedBackgroundView to pre set the content for selected cellĀ“s.
NOTE: this is perfect in my case, so you probably dont want to use it in your case (or let me explain you why you should when you're in a similar position as me)
The code would look like that now:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
[[cell textLabel] setNumberOfLines:0]; // unlimited number of lines
[[cell textLabel] setLineBreakMode:NSLineBreakByWordWrapping];
[[cell textLabel] setFont:[UIFont fontWithName:#"PTSans-Regular" size:33 / 2]];
[[cell textLabel] setTextColor:[self colorFromHexString:COLOR_DEFAULT_TEXT_COLOR]];
cell.indentationLevel = cell.indentationLevel + 2;
//Marker image
imgCell_Marker = [[UIImageView alloc]initWithFrame:CGRectMake(10, 22, 20, 20)];
imgCell_Marker.image=[UIImage imageNamed:#"circle-answer.png"];
imgCell_Marker.tag = TAG_IMAGEMARKERCELL;
[cell.contentView addSubview:imgCell_Marker];
//.. (more data here, just snipped it)
return cell;
}
Here is why I am using this:
I know that my array from where the data for the UITableView comes from is only at top 5 items long. Therefore I can simply delete the if statement in my cellForRowAtIndexPath method of my UITableView. It wont hurt my app (or waste cpu time) because there is so little to do, no know will know.
Still, this solution is kinda ugly. But its okay (I guess) in this case

Tableview images chaging when scrolling using custom tableview

I have a Tableview and i am using the customTableview cell for displaying the cell
in the cell i have 5 buttons (rating buttons) when i click on particular button the image of the button has to changed its working fine but when i am scrolling the tableview again thay are changing to normal rating buttons see the following images for clarity
This is the image before scrolling and clicking nothing on button
after clicking the on rating buttons the image is changing like this
but when scrolling the cells again its changing to first image
please help me out
Code :
- (UITableViewCell )tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
dataCell = (DataCel)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (dataCell==nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"DataCel" owner:self options:nil]; dataCell = [nib objectAtIndex:0];
}
return dataCell;
}
you should save the sate of the button images
and in your
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
insert code to keep them updated
for ex:
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
//create your cell here if it was not created
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
[cell.textLabel setFont:[UIFont boldSystemFontOfSize:13]];
[cell.textLabel setTextColor:[UIColor darkGrayColor]];
[cell.detailTextLabel setFont:[UIFont boldSystemFontOfSize:11]];
[cell.detailTextLabel setTextColor:[UIColor lightGrayColor]];
cell.detailTextLabel.numberOfLines = 2;
}
NSArray *array = [imageArray objectAtIndex:[indexPath row]];
if([[array objectAtIndex:3] isEqual:#"rate3"])
{
//set the code for the rating 3
}
else
{
//insert another rate depending on your object
}
This is because every time you scroll the UITableView, it refreshes its values from the data you provided it ! So the value is not retained. To prevent this from happening every time you scroll the database you can use this
static NSString *cellIdentifier = #"Identifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if(cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:nil];
}
for(id obj in cell.contentView.subviews)
{
if([obj isKindOfClass:[UIImageView class]] || [obj isKindOfClass:[UILabel class]])
{
[obj removeFromSuperview];
}
}
This would not let the values be overlapped.
When scrolled the cells are recreated and so you need the keep the selected values in a seperate array and set it in the cellForRowAtIndexPath method
This happens because every time you scroll the tableview , it re-create tableview cell. therefor you can use array for reused it.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellId = #"cellId";
UITableViewCell *cell = [categoriesTableview dequeueReusableCellWithIdentifier:cellId];
if (cell==nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId];
}
for (UIView *subview in [cell.contentView subviews]) {
[subview removeFromSuperview];
}
// ui goes here
return cell
}

How to make a cell editable

I am currently trying to give user the ability to edit the content of the multiple cells. Once updated, the data will be sent to web service.
Ok right now, as far as I have read, there is only "delete" and "add" row(s). I can't seem to find any guides or tutorials on how to edit the content of cell(s).
Your suggestion(s) and/or advices are much appreciated.
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
You can not edit cell content directly. If you need to edit content then add UITextField or UITextView in cell as its subview. and then access them.
EDIT : You can add textfield as below :
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellIdentifier = #"cellIdentifier";
UITableViewCell *cell;
cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
// ADD YOUR TEXTFIELD HERE
UITextField *yourTf = [[UITextField alloc] initWithFrame:CGRectMake(0, 5, 330.0f, 30)];
[yourTf setBackgroundColor:[UIColor clearColor]];
yourTf.tag = 1;
yourTf.font = [UIFont fontWithName:#"Helvetica" size:15];
yourTf.textColor = [UIColor colorWithRed:61.0f/255.0f green:61.0f/255.0f blue:61.0f/255.0f alpha:1.0f];
yourTf.delegate = self;
[cell addSubview:yourTf];
}
// ACCESS YOUR TEXTFIELD BY REUSING IT
[(UITextField *)[cell viewWithTag:1] setText:#"YOUR TEXT"];
return cell;
}
Implement UITextField delegates and then you can edit cell content using this UITextField.
Hope it helps you.

tableview with checkmark and detail disclosure together

I'm making a tableview with multiple row selected option. So, I used the checkmark accessory type action. I also require to edit/rename the text in the selected row.
Basically, I need to put checkmark (checkbox) on the left side and detail disclosure on the right side of the cell, both functional.
Below code is for checkmark that i have, currently checkmark appears on the right side of the cell.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Navigation logic may go here. Create and push another view controller.
TSIPAppDelegate *appDelegate = (TSIPAppDelegate *)[[UIApplication sharedApplication]delegate];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSString *cellText = cell.textLabel.text;
if (cell.accessoryType==UITableViewCellAccessoryNone)
{
cell.accessoryType=UITableViewCellAccessoryCheckmark;
appDelegate.selectedFile = cellText;
if (prevSP!=indexPath.row) {
cell=[tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:prevSP inSection:0]];
cell.accessoryType=UITableViewCellAccessoryNone;
prevSP=indexPath.row;
}
}
else if (prevSP!=indexPath.row){
cell.accessoryType=UITableViewCellAccessoryNone;
}
}
Any suggestions, please?
When a row selected, checkmark should be enabled/disabled AND disclosure button selected, it should open a new view for editing the selected row.
accessoryType type is of enum UITableViewCellAccessoryType, by definition it will not accept multiple values as it not bitwise enum. So, you have to choose one and mimic the other by custom code.
I'd recommend using the UITableViewCellAccessoryCheckmark accessory type on the tableview and adding a "Detail Disclosure" button to the cell. Unfortunately you can't do exactly what you're looking for, but this is the cleanest alternative approach that I've found.
This is sample code which i have used in one of my app
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.textLabel.text=[NSString stringWithFormat:#"%#",[cellarray objectAtIndex:indexPath.row]];
cell.textLabel.textColor=[UIColor blackColor] ;
cell.textLabel.tag=indexPath.row;
cell.textLabel.font=[UIFont fontWithName:#"HelveticaNeue-Bold" size:15];
// cell.textLabel.highlightedTextColor=[UIColor colorWithRed:242.0f/255.0f green:104.0f/255.0f blue:42.0f/255.0f alpha:1] ;
cell.selectionStyle=UITableViewCellSelectionStyleNone;
}
UIImageView *ima=[[UIImageView alloc]initWithImage:[UIImage imageNamed:#"tick.png"]];
ima.frame=CGRectMake(280, 15, 14, 14);
ima.autoresizingMask=UIViewAutoresizingFlexibleLeftMargin |UIViewAutoresizingFlexibleRightMargin;
int row = [indexPath row];
//cell.accessoryType = (row == selectedRow) ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone;
cell.textLabel.textColor= (row == selectedRow) ? [UIColor colorWithRed:242.0f/255.0f green:104.0f/255.0f blue:42.0f/255.0f alpha:1] : [UIColor blackColor] ;
if (row==selectedRow) {
[cell.contentView addSubview:ima];
}
UIImageView *tempImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"Background.png"]];
[tempImageView setFrame:tableView.frame];
tableView.backgroundView = tempImageView;
[tempImageView release];
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
selectedRow = [indexPath row]; // selected row is of type int declared in .h
[tableView reloadData];
}
This code will have only one checkmark in entire tableView.. You can modify it to have multiple checkmark in that
Hope this helps !!!

Table view with custom cell (programmatically)

So far, I used to create custom nibs to make my cell as I wanted but this time, the height of a cell will change from one to another so that I can't create a fixed-size cell's nib.
So I decided to create it programmatically ... Is the way below the good way to achieve it ?
// Customize the appearance of table view cells.
- (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 *pseudoAndDate = [[UILabel alloc] initWithFrame:CGRectMake(0.0,0.0,320.0,20.0)];
[pseudoAndDate setTag:1];
[cell addSubview:pseudoAndDate];
[pseudoAndDate release];
}
CommentRecord *thisRecord = [comments objectAtIndex:[indexPath row]];
UILabel *label = (UILabel *)[cell viewWithTag:1];
[label setText:[NSString stringWithFormat:#"%# | %#",thisRecord.author,thisRecord.date]];
return cell;
}
or .. am i missing something here ? Cause so far it doesn't seem to work ;)
Thanks,
Gotye.
Why create a label when you don't need to? Use the UITableViewCell's label.
- (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];
}
CommentRecord *thisRecord = [comments objectAtIndex:[indexPath row]];
cell.textLabel.text = [NSString stringWithFormat:#"%# | %#",thisRecord.author,thisRecord.date];
return cell;
}
If your problem is that the height varies from cell to cell you can use the method:
https://developer.apple.com/library/ios/documentation/uikit/reference/UITableViewDelegate_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/UITableViewDelegate/tableView:heightForRowAtIndexPath:
From UITableViewDelagate to achieve it
New link for custom UITableViewCell programmatically Apple Documentation UITableViewCell

Resources