I have a property that is an image in a cell expands,when the pulse in the cell assigned a selectedIndexPath you change the height in the corresponding method , and I want that image to change when the cell is expanded, the problem is that when I expand the cell changes but the image is returned to the previous one that happens when I throw animation to expand the cell is repainted.
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
[tableView deselectRowAtIndexPath:indexPath animated:TRUE];
IACCell *cell = (IACCell *) [tableView cellForRowAtIndexPath:indexPath];
if(!self.selectedIndexPath||![self.selectedIndexPath isEqual:indexPath]){
self.selectedIndexPath=indexPath;
tableView.scrollEnabled = NO;
cell.imageView.image =[UIImage imageNamed:#"image"];
}else{
self.selectedIndexPath=nil;
tableView.scrollEnabled = YES;
}
[tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];
[tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
the cell.imageView.Image changes briefly and the problem I think is in [tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];,
anyone can help me please?
Thanks!
Related
I'm currently using the below code for didSelectRowAtIndexPath. With the way I have my code written now, if a user taps a cell a green checkmark appears. If they tap the same cell again, the green checkmark disappears. That said, I want to make it so that if the user taps a different cell after making a selection, the green checkmark should disappear from the previously selected cell. How can I accomplish this?
ViewController.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
if(_selectedRowIndex && indexPath.row == _selectedRowIndex.row) {
ClientTableViewCell *cell2 = [tableView cellForRowAtIndexPath:indexPath];
cell2.greenCheck.image = [UIImage imageNamed:#""];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
_selectedRowIndex = nil;
}
else { self.selectedRowIndex = indexPath;
ClientTableViewCell *cell2 = [tableView cellForRowAtIndexPath:indexPath];
NSDictionary *client = self.sectionClients[indexPath.section][indexPath.row];
cell2.greenCheck.image = [UIImage imageNamed:#"added.png"];
NSLog(#"SELECTED");
}
[tableView beginUpdates];
[tableView endUpdates];
}
You can store the last selected indexpath, when a new cell is selected, you get the previous cell with the stored indexpath and deselect it.
#implementation ViewController
NSIndexPath *lastIndexPath;
...
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
if (lastIndexPath != nil){
UITableViewCell *oldCell = [self.tableView cellForRowAtIndexPath:lastIndexPath];
oldCell.accessoryType = UITableViewCellAccessoryNone;
}
if(lastIndexPath != indexPath) {
lastIndexPath = indexPath;
UITableViewCell *cell2 = [tableView cellForRowAtIndexPath:indexPath];
cell2.accessoryType = UITableViewCellAccessoryCheckmark;
}else{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
lastIndexPath = nil;
}
[tableView beginUpdates];
[tableView endUpdates];
}
I'm working on a prototype (I'm way too green on Objective C) which has a tableview with two different custom prototype cells, each with their own set of components, layout and height. The expected behavior is that when selected, the row expands and shows cell type b, and the previously selected row returns to the former height and cell type.
Ok, so the issue I'm having is that I can't get the previously selected row to change it's cell type, the height is working ok so I end up displaying a shorter version of the expanded cell but not having the components and layout of the desired cell type, and if I scroll through the tableview and return to the location where the previously selected row is it displays the correct cell type, as if it hasn't refreshed the rest of the rows.
Here's my code for tableView cellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier;
UITableViewCell *cell = nil;
if(indexPath.row == self.selectedIndex){
CellIdentifier = #"ExpandedCell";
CollapsedCell *collapsedCell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
cell = collapsedCell;
}else{
CellIdentifier = #"LocationCell";
LocationCell *locationCell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
locationCell.transparentBorder.layer.borderWidth = 5.0f;
locationCell.transparentBorder.layer.borderColor = [UIColor colorWithRed:255/255 green:255/255 blue:255/255 alpha:0.7].CGColor;
cell = locationCell;
}
BHPlace *currentPlace = self.data[indexPath.row];
NSString *name = currentPlace.name;
LocationCell *locationCell = (LocationCell*)cell;
locationCell.nameLabel.text = name;
cell.backgroundColor = [UIColor clearColor];
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
return cell;
}
and here's the code for my didSelectRowAtIndexPath:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
[self.tableView deselectRowAtIndexPath:[NSIndexPath indexPathForRow:self.selectedIndex inSection:0] animated:YES];
[self.tableView beginUpdates];
self.selectedIndex = (int)indexPath.row;
NSArray *paths = #[indexPath];
[self.tableView reloadRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationFade];
[self.tableView endUpdates];
[self goToMarker:self.data[indexPath.row]];
}
As usual I'm sure it's a simple issue and there's something I'm not getting right but can't find the right approach,
Thank you all for your time
You just need to reload both the previously selected and the newly selected rows -
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
NSMutableArray *paths=[NSMutableArray new];
if (self.selectedIndexPath != nil) {
[paths addObject:self.selectedIndexPath];
[tableView deselectRowAtIndexPath:self.selectedIndexPath animated:YES];
}
[self.tableView beginUpdates];
self.selectedIndexPath = indexPath;
[paths addObject:indexPath];
[self.tableView reloadRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationFade];
[self.tableView endUpdates];
[self goToMarker:self.data[indexPath.row]];
}
Note that I changed your int property to an NSIndexPath * self.selectedIndexPath
I have a static tableview that shows a date picker when the appropriate cell is selected. The didSelectRowAtIndexPath triggers the show/hide of the date picker cell; however, it's not until the second selection that scrollToRow is executed and the picker cell is hidden.
-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell* cell = [tableView cellForRowAtIndexPath:indexPath];
[tableView beginUpdates];
if (cell == self.dateCell){
self.dateOpen = !self.isdateOpen;
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:3 inSection:1] atScrollPosition:UITableViewScrollPositionTop animated:YES];
}
[self.tableView reloadData];
[self.tableView endUpdates];
}
Any Ideas of where I've gone astray??
Thank You!!
EDIT: I forgot to add, it's the last row that's expanding with the date cell... I'm wondering how that would affect it. Although, I did just copy/paste a few cells to make it not the last row and it didn't help.
I am desperately trying to achieve the following effect: I have got a tableview where I would like to expand the cells on selection and show some additional information on it. I reuse table cells, just FYI. In the past I was able to achieve such an effect in another application, but this just does not seem to work for me at all. All the methods that are vital for this to happen are called and the row expands beautifully, but the additionalInfo table in the showExpandedContents method just will not appear!
If I create the additionalInfo table in the initialisation of the cell, the table will appear but when I then try to load the data (and by that, also the cells) it just won't reload the table.
But the method that is responsible for this (showExpandedContents) table is definitely called.
If I initialise AND set up the table in the initialisation code of the cell everything works fine.
So here is some code for you:
Here is the cell setup:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *cellID = #"MyCustomCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
if(cell == nil){
cell = [[MyCustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID];
}
((MyCustomCell*)cell).data = [arrayToDisplay objectAtIndex:indexPath.row];
return cell;
}
Here is the selection method:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
[tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];
//setting the current cell as the expandedRow, so that I can collapse it later
expandedRow = [tableView cellForRowAtIndexPath:indexPath];
[((MyCustomCell*)expandedRow) showExpandedContents];
[tableView beginUpdates];
[self changeRowHeightAtIndex:indexPath.row height:330];
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView endUpdates];
}
Here is the -showExpandedContents method in MyCustomCell where I would like to display the additional information:
-(void)showExpandedContents{
additionalInfo = [[UITableView alloc] initWithFrame:CGRectMake(0, 80, self.frame.size.width, 250)];
[additionalInfo loadContent];
additionalInfo.backgroundColor = UIColorFromRGB(0xf9f9f9, 1.0);
additionalInfo.layer.zPosition = MAXFLOAT;
[self.contentView addSubview:additionalInfo];
}
Looks like your
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
is giving you a fresh cell, different than the one that had showExpandedContents called.
Removing this line should fix the problem.
I want to have the same behavior as Twitter app when selecting a tweet that is : expanding the row and adding supplementary content.
So this is not only a basic row resize. I think i need 2 different custom cells, so i did something like that :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([indexPath compare:self.selectedIndexPath] != NSOrderedSame) {
FirstCell *cell = [tableView dequeueReusableCellWithIdentifier:#"FirstCell"];
if (!cell) {
cell = [[FirstCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"FirstCell"];
}
cell.firstnameLabel.text = [[self.items objectAtIndex:indexPath.row] objectForKey:#"firstname"];
return cell;
}
else {
SecondCell *cell = [tableView dequeueReusableCellWithIdentifier:#"SecondCell"];
if (!cell) {
cell = [[SecondCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"SecondCell"];
}
cell.firstnameLabel.text = [[self.items objectAtIndex:indexPath.row] objectForKey:#"firstname"];
cell.lastnameLabel.text = [[self.items objectAtIndex:indexPath.row] objectForKey:#"lastname"];
return cell;
}
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if ([indexPath compare:self.selectedIndexPath] == NSOrderedSame) {
return 80.0;
} else {
return 44.0;
}
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
self.selectedIndexPath = indexPath;
[tableView reloadData];
}
My problem here is that i want to keep a fluid animation like Twitter app which is not my case because of [tableView reloadData] (which is mandatory i think since i have 2 different custom cell).
So anyone knows a workaround to my needed or maybe someone knows how Twitter app is handling this animation stuff ?
You want to reload that cell with an animation:
[tableView beginUpdates];
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView endUpdates];
[tableView beginUpdates];
[tableView endUpdates];
this triggers an update of the cell row sizes for the whole tableView.... referenced from :iPhone - Smooth animation for UITableViewCell height change including content update
Happy Coding!
It is actually rather easy to implement this using two custom cells like you originally intended by just combining your original code with rooster117's solution. Replace [tableView reloadData] in your tableView:didSelectRowAtIndexPath: with:
[tableView beginUpdates];
[tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
[tableView endUpdates];
and you should have your solution.