i have a tableview. i add image to the cells when clicked on the cell in didselectrow method by using cell.conteview addsubview. but the problem is if i click on 1st cell it changes the image and when i click on another cell image will appears but the old image is not removed from the previous cell. This is happening for all cells in table view if a cell is clicked.
i used the code as follows
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
Practices *bPractices = [topics objectAtIndex:indexPath.row];
UIImageView *clickView;
//[cell.contentView removeFromSuperview];
clickView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 315, 82)];
clickView.image = [UIImage imageNamed:#"list_bg_hover.png"];
[cell.contentView addSubview:clickView];
[clickView release];
UILabel *labelText= [[UILabel alloc]initWithFrame:CGRectMake(90, 30, 320, 20)];
labelText.text=bPractices.practices_title;
labelText.backgroundColor=[UIColor clearColor];
[cell.contentView addSubview:labelText];
}
pls help me how to solve this issue
Thanks in advance
I did something similar, but not with images but buttons. If a cell wasn't selected yet and gets tabbed, the size is changed and a certain and individual number of buttons is added. If another cell was selected, this one gets closed.
Code from form the UITableViewController
interface:
int openedCellIndex;//<-what cell is selected
int buttonCounter;
implementation:
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if ( indexPath.row != openedCellIndex )
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[TRTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier]
autorelease];
//cell.frame = CGRectMake (0,0, 320, 100);
}
id <P_E_P1Article> article = [self.fetchedResultsController objectAtIndexPath:indexPath];
cell.textLabel.text = article.name;
if ( self.cellBackgroundColor )
cell.backgroundColor = self.cellBackgroundColor;
return cell;
}
else {
//get article
id <P_E_P1Article> article = [self.fetchedResultsController objectAtIndexPath:indexPath];
//number of buttons
int buttons = [article.specification count];
int height = 50 * ceil(buttons / 2) + 50;
//construct special cell
UITableViewCell *cell = [[[TRTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:#"CellBig"]
autorelease];
cell.frame = CGRectMake (0,0, 320, 150);
cell.textLabel.text = #"";
//add label
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(20, 10, 280, 30)];
label.font = [UIFont boldSystemFontOfSize:17];
label.text = article.name;
label.backgroundColor = [UIColor clearColor];
[cell addSubview:label];
[label release];
if ( buttonMapper == nil )
self.buttonMapper = [NSMutableDictionary dictionaryWithCapacity:10];
//NSLog (#" bla: %#", article.isFreePrice);
//see if we have a free prized article
//create the buttons
NSEnumerator *enumerator = [article.specification objectEnumerator];
id <P_E_P1ArticleSpecification> spec;
int count = 0;
NSArray *specs =
[self sortedArticleSpecifications:article];
for ( spec in specs ) {
//see which row and col the button is in
int row = floor ( count / 2 );
int col = count % 2;
//define button position
int left = 20 + col * 145;
int top = 45 + row * 50;
//create button
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame = CGRectMake(left, top, 135, 40);
[cell addSubview:button];
[button setTitleColor:[UIColor blackColor] forState:0];
[button addTarget:self
action:#selector(buttonTapped:)
forControlEvents:UIControlEventTouchUpInside];
//remember which article the button is attached to
buttonCounter++;
button.tag = buttonCounter;
[buttonMapper setValue:spec forKey:[NSString stringWithFormat:#"bla%d",buttonCounter]];
count++;
}
if ( self.cellBackgroundColor )
cell.backgroundColor = self.cellBackgroundColor;
return cell;
}
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if ( openedCellIndex == indexPath.row )
{
id <P_E_P1Article> article = [self.fetchedResultsController objectAtIndexPath:indexPath];
int count = [article.specification count];
int height = 50 * ceil(count / 2.) + 50;
return height;
}
return 50;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
[self openRow:indexPath.row];
[self.searchBar resignFirstResponder];
}
- (void) openRow:(int) index
{
if ( index == openedCellIndex ) return;
int oldIndex = openedCellIndex;
openedCellIndex = index;
NSUInteger indexArr[] = {0, oldIndex};
NSIndexPath *oldPath = [NSIndexPath indexPathWithIndexes:indexArr length:2];
NSUInteger indexArr2[] = {0, openedCellIndex};
NSIndexPath *newPath = [NSIndexPath indexPathWithIndexes:indexArr2 length:2];
//update view
[(UITableView *)self.view beginUpdates];
if ( oldIndex >= 0 )
[(UITableView *)self.view reloadRowsAtIndexPaths:[NSArray arrayWithObject:oldPath]
withRowAnimation:UITableViewRowAnimationFade];
if (openedCellIndex >=0 )
[(UITableView *)self.view reloadRowsAtIndexPaths:[NSArray arrayWithObject:newPath]
withRowAnimation:UITableViewRowAnimationFade];
[(UITableView *)self.view endUpdates];
}
You could also subclass UITableViewCell and handle the select/deselect process in the setSelected method. Then use your custom cell as the type for the prototype cell instead of the default.
Related
I am using an Expandable UITableview created by Tom Fewster. I want to tweak the example using two NSMutableArrays, which is a scenario whereby if someone wants to populate an expandable/collapse treeview table from webservice json data would want to achieve. So since in his example the GroupCell does not have an array of, I am wondering how can I do it? Please bear in mind that my Objective-C is still rusty hence, I'm asking this question.
With my attempt is only displaying the first ObjectAtIndex:indexPath:0 for the group.
I want to be able to populate the table and get output like this;
Group A
Row 1a
Row 2a
Row 3a
Group B
Row 1b
Row 2b
Group C
Row 1c
Row 2c
Row 3c
and so on.
You may use JSON data as well to explain your answer if you understand it better that way.
Here i want to populate the table with JSON data so the GroupCell show class_name and rowCell show subject_name. This is the console of what I am parsing from the JSON web-service;
(
{
"class_id" = 70;
"class_name" = Kano;
subject = (
"subject_id" = 159;
"subject_name" = "Kano Class";
}
);
},
{
"alarm_cnt" = 0;
"class_id" = 71;
"class_name" = Lagos;
subject = (
"subject_id" = 160;
"subject_name" = "Lagos Class";
}
);
},
{
"alarm_cnt" = 3;
"class_id" = 73;
"class_name" = Nasarawa;
subject = (
"subject_id" = 208;
"subject_name" = "DOMA Class";
},
"subject_id" = 207;
"subject_name" = "EGGON Class";
},
"subject_id" = 206;
"subject_name" = "KARU Class";
},
"subject_id" = 209;
"subject_name" = "LAFIA Class";
},
"subject_id" = 161;
"subject_name" = "Nasarawa State Class";
}
);
},
{
"alarm_cnt" = 2;
"class_id" = 72;
"class_name" = Rivers;
subject = (
"subject_id" = 162;
"subject_name" = "Rivers Class";
}
);
}
)
I have tried this here is my snippet
- (UITableViewCell *)tableView:(ExpandableTableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"RowCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
NSDictionary *d=[_sitesJson objectAtIndex:0] ;
NSArray *arr=[d valueForKey:#"subject_name"];
NSDictionary *subitems = [arr objectAtIndex:0];
NSLog(#"Subitems: %#", subitems);
NSString *siteName = [NSString stringWithFormat:#"%#",subitems];
cell.textLabel.text =siteName;
//}
NSLog(#"Row Cell: %#", cell.textLabel.text);
// just change the cells background color to indicate group separation
cell.backgroundView = [[UIView alloc] initWithFrame:CGRectZero];
cell.backgroundView.backgroundColor = [UIColor colorWithRed:232.0/255.0 green:243.0/255.0 blue:1.0 alpha:1.0];
return cell;
}
- (UITableViewCell *)tableView:(ExpandableTableView *)tableView cellForGroupInSection:(NSUInteger)section
{
static NSString *CellIdentifier = #"GroupCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
UILabel *textLabel = (UILabel *)[cell viewWithTag:2];
NSDictionary *d2 = [_regionsJson objectAtIndex:0];
NSArray *arr2 = [d2 objectForKey:#"class_name"];
NSString *regions = [[arr2 objectAtIndex:section]objectAtIndex:0];
textLabel.textColor = [UIColor whiteColor];
textLabel.text = [NSString stringWithFormat: #"%# (%d)", regions, (int)[self tableView:tableView numberOfRowsInSection:section]];
NSLog(#"Group cell label: %#", textLabel.text);
// We add a custom accessory view to indicate expanded and colapsed sections
cell.accessoryView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"ExpandableAccessoryView"] highlightedImage:[UIImage imageNamed:#"ExpandableAccessoryView"]];
UIView *accessoryView = cell.accessoryView;
if ([[tableView indexesForExpandedSections] containsIndex:section]) {
accessoryView.transform = CGAffineTransformMakeRotation(M_PI);
} else {
accessoryView.transform = CGAffineTransformMakeRotation(0);
}
return cell;
}
He, just need to update one single method little bit way
- (UITableViewCell *)tableView:(ExpandableTableView *)tableView cellForGroupInSection:(NSUInteger)section
{
static NSString *CellIdentifier = #"GroupCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
NSIndexPath *indexPath;
NSString *regions = [[_dataGroup objectAtIndex:section]objectAtIndex:0];
cell.textLabel.text = [NSString stringWithFormat: #"%# ", regions];
// We add a custom accessory view to indicate expanded and colapsed sections
cell.accessoryView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"ExpandableAccessoryView"] highlightedImage:[UIImage imageNamed:#"ExpandableAccessoryView"]];
UIView *accessoryView = cell.accessoryView;
if ([[tableView indexesForExpandedSections] containsIndex:section]) {
accessoryView.transform = CGAffineTransformMakeRotation(M_PI);
} else {
accessoryView.transform = CGAffineTransformMakeRotation(0);
}
return cell;
}
May help it you.
HTH, Enjoy Coding !!
I think you need to create a TableView which will have a sections array, and each sections row will be populated using the corresponding sections array. Tapping on a section will expand it and it's all rows will be visible.
To meet your requirements, you could follow the below steps as well -
1) Your modal should have a array for sections. The sections array will contain the sections objects, name of the section and corresponding array of the rows.
2) Implement the data source methods of the table view like
- (NSInteger) numberOfSectionsInTableView:(UITableView *)tableView
{
return [section count];
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 50; // sections height
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return nil;
}
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
return nil;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UIView *view = [[[UIView alloc] initWithFrame:CGRectMake(0 , 0, tableView.frame.size.width , 50)] autorelease];
[view setBackgroundColor:[UIColor redColor]];
view.layer.masksToBounds = YES;
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(5 , 2 , view.frame.size.width - 10 , view.frame.size.height - 3)];
label.text = ((SectionObject *)[section objectAtIndex:indexPath.section]).sectionName;
label.backgroundColor = [UIColor clearColor];
label.textAlignment = NSTextAlignmentLeft;
label.textColor = [UIColor WwhiteColor];
label.clipsToBounds = YES;
label.font = [UIFont fontWithName:#"HelveticaNeue-CondensedBold" size:14.0f];
label.layer.masksToBounds = YES;
UIImageView *arrowImage = [[UIImageView alloc] initWithFrame:CGRectMake(view.frame.size.width - 30, 0, 17 , 17)];
[arrowImage setCenter:CGPointMake(arrowImage.center.x , (view.frame.size.height/2) ) ];
if(section == self.m_currentSelectedSection)
[arrowImage setImage:self.m_upArrowImage];
else
[arrowImage setImage:self.m_downArrowImage];
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, view.frame.size.width, view.frame.size.height)];
button.tag = section;
[button addTarget:self action:#selector(sectionTapped:) forControlEvents:UIControlEventTouchUpInside];
button.backgroundColor = [UIColor clearColor];
[view addSubview:label];
[label release];
[view addSubview:arrowImage];
[arrowImage release];
[view addSubview:button];
[button release];
view.clipsToBounds = YES;
return view;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSInteger count = 0;
if(self.m_currentSelectedSection == section)
count = [((SectionObject *)[section objectAtIndex:indexPath.section]).rowArray count];
return count;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 40.0;
}
- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString * cellId = #"cellIdentifier";
UITableViewCell *cell = nil;
cell = (UITableViewCell *) [tableView dequeueReusableCellWithIdentifier:cellId];
if(cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier] autorelease];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
//customize cell
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:NO];
}
When ever any section will be tapped following event will be invoked
- (void) sectionTapped:(UIButton *)button
{
self.m_currentSelectedSection = button.tag;
[self performSelector:#selector(refreshView) withObject:nil afterDelay:POINT_ONE_SECOND];
if(m_winnerSlotList->at(self.m_currentSelectedSection).m_leaderboardList.size())
[self.m_leaderboardTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:button.tag] atScrollPosition:UITableViewScrollPositionTop animated:YES];
UIView *baseView = [button superview];
if(baseView)
{
for(int ii = 0 ; ii < [[baseView subviews] count] ; ii++ )
{
UIView *anyView = [[baseView subviews] objectAtIndex:ii];
if([anyView isKindOfClass:[UIImageView class]])
[(UIImageView *)anyView setImage:self.m_upArrowImage];
}
}
}
Initialize self.m_currentSelectedSection = 0, for the first time, this will show the rows for 0th section. As any section is tapped it's rows will be visible (corresponding section rows will expand) and the rows for the previous selected section will be hidden(previous section rows will collapse).
If you need to show more than one section as expanded than you need to keep track of all the section whether a section is expanded or not and accordingly load show/ hide the cells for the corresponding section.
This is how my table is populated :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
CellNewsInfo *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
if (!cell) {
cell=[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"cell"];
}
// Set up the cell
int storyIndex = [indexPath indexAtPosition: [indexPath length] - 1];
NSString *titleArticle=[[stories objectAtIndex: storyIndex] objectForKey: #"title"];
titleArticle = [titleArticle stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
if (indexPath.row==0) {
scr=[[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 320, 200)];
scr.tag = 1;
scr.autoresizingMask=UIViewAutoresizingNone;
[cell addSubview:scr];
[self setupScrollView:scr];
UIPageControl *pgCtr = [[UIPageControl alloc] initWithFrame:CGRectMake(120, 170, 80, 36)];
[pgCtr setTag:12];
pgCtr.backgroundColor = [UIColor clearColor];
pgCtr.numberOfPages=5;
pgCtr.tintColor=[UIColor redColor];
pgCtr.pageIndicatorTintColor=[UIColor blueColor];
self.pageControl.hidden=YES;
pgCtr.currentPageIndicatorTintColor = [UIColor redColor];
pgCtr.autoresizingMask=UIViewAutoresizingNone;
[cell addSubview:pgCtr];
}
else{
cell.title.text=titleArticle;
cell.title.numberOfLines=2;
why when i scroll it , the first cell is reloading ? i just want to have that scroll view only once at the beginig .
The reason your scrollview is being added again is that the cells are being reused once they are deallocated.
You should look into creating your own custom cells if you are going to display multiple cells types in one tableView, or even using two different cell identifiers depending on if the row is 0.
CellNewsInfo *cell;
if (indexPath.row == 0) {
cell = [tableView dequeueReusableCellWithIdentifier:#"scrollCell" forIndexPath:indexPath];
if ([cell viewWithTag:1]) {
scr = [cell viewWithTag:1];
}
else {
scr=[[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 320, 200)];
scr.tag = 1;
}
// continue customization here with scrollview
}
else {
cell = [tableView dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
// continue customization here without scroll view
}
return cell;
I've added a UIScrollView in each UITableViewCell of a UITableView.
This is my code.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString* CellIdentifier = #"Cell";
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
UIScrollView *propertyScrollView;
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
propertyScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, tableView.frameWidth, 100)];
[propertyScrollView setContentSize:CGSizeMake(10*tableView.frameWidth, 100)];
[propertyScrollView setPagingEnabled:YES];
propertyScrollView.delegate = self;
propertyScrollView.tag = indexPath.row;
[[cell contentView] addSubview:propertyScrollView];
propertyScrollView.backgroundColor = [UIColor blackColor];
int pagingIndex = [[m_pagingIndexArray objectAtIndex:indexPath.row]intValue];
[propertyScrollView setContentOffset:CGPointMake(pagingIndex*propertyScrollView.frameWidth, 0)];
for(int i=0;i<10;i++)
{
UIButton *singleImage = [[UIButton alloc]initWithFrame:CGRectMake(i*tableView.frameWidth, 0, propertyScrollView.frameWidth, propertyScrollView.frameHeight)];
[propertyScrollView addSubview:singleImage];
singleImage.titleLabel.text = [NSString stringWithFormat:#"%d",i];
singleImage.titleLabel.textColor = [UIColor blackColor];
singleImage.titleLabel.font = systemFontBoldTypeOfSize(20);
[singleImage setImage:[horizentalImagesArray objectAtIndex:i] forState:UIControlStateNormal];
singleImage.backgroundColor = [UIColor whiteColor];
}
else
{
propertyScrollView.tag = indexPath.row;
int pagingIndex = [[m_pagingIndexArray objectAtIndex:indexPath.row]intValue];
[propertyScrollView setContentOffset:CGPointMake(pagingIndex*propertyScrollView.frameWidth, 0)];
}
return cell;
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
int pageIndex = scrollView.contentOffset.x/scrollView.frameWidth;
[m_pagingIndexArray replaceObjectAtIndex:scrollView.tag withObject:[NSString stringWithFormat:#"%d",pageIndex]];
}
- (void)viewDidLoad {
[super viewDidLoad];
m_pagingIndexArray = [[NSMutableArray alloc]init];
for(int i=0;i<10;i++)
{
[m_pagingIndexArray addObject:#"0"];
}
}
I'm adding 10 UIButtons in a single UIScrollView(Paging Enabled).
The problem is, if I scroll any one of the UITableViewCell's scrollview and move to bottom cells, I can see some other UITableViewCell's scrollviews also scrolled to that content offset point.
I want all my UITableview cell's UIScrollView to scroll independently. How can I achieve it? Please help me to sort out this issue.
You are keeping the current page number in m_pagingIndexArray, and the same array is used for all the cells, so suppose if it contains the page number as 3, then it will be applicable for all the cells.
Also you need to reset the text and image of each button for each cell if it's being reused as I have added below-
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell* cell = nil;
UIScrollView *propertyScrollView;
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
propertyScrollView = [[[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, tableView.frameWidth, 100)] autorelease];
[propertyScrollView setContentSize:CGSizeMake(10*tableView.frameWidth, 100)];
[propertyScrollView setPagingEnabled:YES];
propertyScrollView.delegate = self;
propertyScrollView.tag = indexPath.row;
[[cell contentView] addSubview:propertyScrollView];
propertyScrollView.backgroundColor = [UIColor blackColor];
int pagingIndex = [[m_pagingIndexArray objectAtIndex:indexPath.row]intValue];
[propertyScrollView setContentOffset:CGPointMake(pagingIndex*propertyScrollView.frameWidth, 0)];
for(int i=0;i<10;i++)
{
UIButton *singleImage = [[[UIButton alloc]initWithFrame:CGRectMake(i*tableView.frameWidth, 0, propertyScrollView.frameWidth, propertyScrollView.frameHeight)] autorelease];
[propertyScrollView addSubview:singleImage];
singleImage.titleLabel.text = [NSString stringWithFormat:#"%d",i];
singleImage.titleLabel.textColor = [UIColor blackColor];
singleImage.titleLabel.font = systemFontBoldTypeOfSize(20);
[singleImage setImage:[horizentalImagesArray objectAtIndex:i] forState:UIControlStateNormal];
singleImage.backgroundColor = [UIColor whiteColor];
}
return cell;
}
Your code is correct for the case if cell is not reused, but as the cells are reused you need to set the content offset for scroll view of each cell if they are reused.
You need to write an else case -
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(cell == nil)
{
// your code
}
else
{
// reset the content offset of the scroll view as per your needs for the reused cells
}
return cell;
}
I have this collapsable UITableView where there is a UITextField and a UIButton in the last cell in each table section. I would like to send the text in the UITextField to the function that is called by the UIButton that is next to it in the same cell, but I am baffled in how to achieve this. Thanks in advance for the help!
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [_tableView dequeueReusableCellWithIdentifier:nil];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if ([self tableView:_tableView canCollapseSection:indexPath.section])
{
int num = 1;
if (self.chat[indexPath.section - 1][#"num"] != nil)
num = [self.chat[indexPath.section - 1][#"num"] intValue] + 1;
if (!indexPath.row)
{
cell.textLabel.text = self.chat[indexPath.section - 1][#"msg"]; // only top row showing
if ([expandedSections containsIndex:indexPath.section])
{
cell.accessoryView = [DTCustomColoredAccessory accessoryWithColor:[UIColor grayColor] type:DTCustomColoredAccessoryTypeUp];
}
else
{
cell.accessoryView = [DTCustomColoredAccessory accessoryWithColor:[UIColor grayColor] type:DTCustomColoredAccessoryTypeDown];
}
}
else if (indexPath.row < num && indexPath.row >= 1)
{
cell.textLabel.text = self.chat[indexPath.section - 1][key];
cell.accessoryView = nil;
}
else
{
///////////////////////////////////////////
////////This is the important part/////////
///////////////////////////////////////////
UITextField *field = [[UITextField alloc] initWithFrame:CGRectMake(14, 6, 245, 31)];
self.sendButton = [[UIButton alloc] initWithFrame:CGRectMake(265, 1, 50, 40)];
[self.sendButton setTitle:#"Reply" forState:UIControlStateNormal];
[self.sendButton setTitleColor:UIColorFromRGB(0x960f00) forState:UIControlStateNormal];
[cell addSubview:self.sendButton];
[self.sendButton addTarget:self action:#selector(sendReply:) forControlEvents:UIControlEventTouchUpInside];
[cell addSubview:field];
cell.accessoryView = nil;
}
}
else
{
cell.accessoryView = nil;
cell.textLabel.text = #"Normal Cell";
}
return cell;
}
Give some unique tag to textfield and button by below way:
///////////////////////////////////////////
////////This is the important part/////////
///////////////////////////////////////////
UITextField *field = [[UITextField alloc] initWithFrame:CGRectMake(14, 6, 245, 31)];
self.sendButton = [[UIButton alloc] initWithFrame:CGRectMake(265, 1, 50, 40)];
[self.sendButton setTitle:#"Reply" forState:UIControlStateNormal];
[self.sendButton setTitleColor:UIColorFromRGB(0x960f00) forState:UIControlStateNormal];
self.sendButton.tag = indexPath.section *1000 + indexPath.row;
[cell addSubview:self.sendButton];
[self.sendButton addTarget:self action:#selector(sendReply:) forControlEvents:UIControlEventTouchUpInside];
field.tag = self.sendButton.tag + 1;
[cell addSubview:field];
cell.accessoryView = nil;
Now on button event,
-(void) sendReply:(UIButton *)sender
{
UITextField *field = [YOOUR_TABLE_VIEW viewWithTag:sender.tag + 1];
//Do you coding here
}
Make a Custom UITableViewCell that has uitextfield and a button on it and make a protocol/delegate of that custom uitableviewcell you've created.. so you can have more control of your code and the event of your button in the future..
check this tutorial: http://www.codigator.com/tutorials/ios-uitableview-tutorial-custom-cell-and-delegates/
cheers
For this,
In cellForRowAtIndexPath: method where you are allocating the send button add one line just to give some identifier to send button as below,
[self.sendButton setAccessibilityIdentifier:[NSString stringWithFormat:#"%d#%d",indexPath.row,indexPath.section]];
Now, in sendReply: method,
//First get the row and section information
NSString *str=[sender accessibilityIdentifier];
NSArray *arr=[str componentsSeparatedByString:#"#"];
//Get the index path
NSIndexPath *iRowId =[NSIndexPath indexPathForRow:[[arr objectAtIndex:0] intValue] inSection:[arr objectAtIndex:1] intValue]];
//get the cell
UITableViewCell *objCell=(UITableViewCell*)[tblviwBasketCell cellForRowAtIndexPath:iRowId];
Now objCell will be the cell in which you have added the button and text view. so get the subviews of objCell and access the textfield to get the text.
As you say, there is a text field in each section. You should set the tag of your UIButton and UITextField same as indexPath.section.
Then, in the target method, use this tag value to get the relevant cell from the relevant section, and iterate over it's subviews to get your textField.
In the target method, you should do something like this:
- (void) sendReply:(id)sender {
int section = [(UIButton*)sender tag];
int row = [myTableView numberOfRowsInSection:section] - 1;//assuming it is the last cell in the section that contains your textField.
NSIndexPath* indexPath = [NSIndexPath indexPathForRow:row inSection:section];
UITableViewCell* cell = [myTableView cellForRowAtIndexPath:indexPath];
for (UIView* vu in cell.subviews) {
if ([vu isKindOfClass:[UITextField class]]) {
NSString* textString = [(UITextField*)vu text];
//perform any tasks you want with the text now
}
}
}
You can simply use viewWithTag:, since it does an iterative search, but all the extra code is to avoid iterating over all the cells before reaching your relevant cell.
My table only has 2 sections. I have a UITextView as a subview in the 2nd section of my table. and a list of possible quotes in the first section.
I'm having a problem where once the user selects a particular quote which gets "pasted" into the UITextView like so:
replyTextView.text = [NSString stringWithFormat:#"#%# UserName writes... \n[\"%#\"]", replyPostCode,[separatedString objectAtIndex:indexPath.row]];
or types text into the textview, after they scroll away from the textview so it's off the screen it gets cleared. I guess this is because I keep releasing it from my table..
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
NSString *replyCellIdentifier = #"replyCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
if ([indexPath section] == 0) {
cell = [self CreateMultilinesCell:CellIdentifier];
}
else if ([indexPath section] == 1) {
//NSLog(#"TextField");
cell = [self CreateMultilinesCell:replyCellIdentifier];
if ([indexPath row] == 0) {
replyTextView = [[UITextView alloc] initWithFrame:CGRectMake(0, 0, 300, 150)];
//replyTextView.adjustsFontSizeToFitWidth = YES;
replyTextView.textColor = [UIColor blackColor];
replyTextView.keyboardType = UIKeyboardTypeASCIICapable;
replyTextView.returnKeyType = UIReturnKeyDefault;
replyTextView.backgroundColor = [UIColor whiteColor];
replyTextView.autocorrectionType = UITextAutocorrectionTypeNo;
replyTextView.autocapitalizationType = UITextAutocapitalizationTypeNone;
replyTextView.textAlignment = UITextAlignmentLeft;
replyTextView.tag = 0;
replyTextView.editable = YES;
replyTextView.delegate = self;
replyTextView.scrollEnabled = YES;
//[replyTextView becomeFirstResponder];
//replyTextView.clearButtonMode = UITextFieldViewModeNever;
//[replyTextView setEnabled: YES];
[cell.contentView addSubview:replyTextView];
[replyTextView release];
//cell.detailTextLabel.text = #"";
}
}
}
//NSLog(#"%d", [indexPath section]);
if ([indexPath section] == 0) {
cell.detailTextLabel.text = [separatedString objectAtIndex:indexPath.row];
}
return cell;
}
I'm just wondering just what is the best way to keep the text in my UITextView when the user scrolls the uitextview off the screen and back again?
update
- (UITableViewCell*) CreateMultilinesCell :(NSString*)cellIdentifier
{
//NSLog(#"Entering CreateMultilinesCell");
UITableViewCell *cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:cellIdentifier] autorelease];
cell.detailTextLabel.numberOfLines = 0;
cell.detailTextLabel.font = [self SubFont];
cell.detailTextLabel.textColor = [UIColor colorWithRed:10.0/255 green:10.0/255 blue:33.0/255 alpha:1.0];
[cell setBackgroundColor:[UIColor clearColor]];//]colorWithRed:.98 green:.98 blue:.99 alpha:1.0]];
[self.tableView setBackgroundColor:[UIColor clearColor]];//colorWithRed:.94 green:.96 blue:.99 alpha:1.0]];
//NSLog(#"Exiting CreateMultilinesCell");
return cell;
}
The easiest solution is to use a different cell identifier for the two types of cells.
Edit: I see you are using two different types, but you are not taking that into account in the dequeue call.