In my app I am trying to display Mkmapview in UITableView. When I tap the cell, it has to expand and show the map. Then if I tap another cell, it should act again expand and show gallery view , the previous cell must collapse and map should be hide.
thanks in advance,
You have to keep track of the state (or height) of the expanding/collapsing cell. Then report that height in tableView:heightForRowAtIndexPath:. Then add the code below to trigger the resizing.
[self.tableView beginUpdates];
[self.tableView endUpdates];
For example:
- (void)toggleMapCell {
_mapCellExpanded = !_mapCellExpanded;
if (_mapCellExpanded)
_mapCellHeight = 200.0;
else
_mapCellHeight = 44.0;
[self.tableView beginUpdates];
[self.tableView endUpdates];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if ([indexPath isEqualTo:_mapCellIndexPath])
return _mapCellHeight;
else
return 44.0;
}
If you have to re-layout the cell's content. I think the best place is to do it in the cell's layoutSubviews.
Related
I try to make cells expand/collapse with drop-down like animation, so when table view recalculates height it moves down other cells below the one that was tapped,
but if the tapped cell top margin is not entirely visible, table view changes its height update behavior by moving all above cells up:
http://imgur.com/CldzuFf
Is there a way to make cells expand with top-to-bottom behavior always?
Reloading cells like this:
[self.tableView beginUpdates];
[self.tableView reloadRowsAtIndexPaths:arrayToReload withRowAnimation:UITableViewRowAnimationBottom];
[self.tableView endUpdates];
Just set the contentOffset based on selected row
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell * theCell = (UITableViewCell *)[tableView
cellForRowAtIndexPath:indexPath];
CGPoint tableViewCenter = [tableView contentOffset];
tableViewCenter.y += myTable.frame.size.height/2;
[tableView setContentOffset:CGPointMake(0,theCell.center.y-65) animated:YES]; // need to customize the y offset 65 to your value
// reload row here
}
I have a standard tableview of .Subtitle style. However, I would like to show the detailed text only when the cell is swiped. I would like to increase the height of the swiped cell (and only the swiped cell) to display the detailed text. I have not tried creating 2 cell prototypes and swapping the cell on the swipe and I am not experienced enough to implement it. I could implement the optional function heightForRowAtIndexPath but that would change every cell unconditionally.
I would appreciate any ideas on how to do this.
In tableViewheightForRowAtIndexPath method, you could change specific cell height, and keep other cells in the same height.
you can check the below sample code
NSIndexPath *selectedCellIndexPath;
//
- (void)tableView:(UITableView *)tableViewdidSelectRowAtIndexPath:(NSIndexPath *)indexPath {
selectedCellIndexPath = indexPath;
// Forces the table view to callheightForRowAtIndexPath
[tableView reloadRowsAtIndexPaths:[NSArrayarrayWithObject:indexPath]withRowAnimation:UITableViewRowAnimationNone];
}
- (CGFloat)tableView:(UITableView *)tableViewheightForRowAtIndexPath:(NSIndexPath *)indexPath {
// Note: Some operations like calling [tableViewcellForRowAtIndexPath:indexPath]
// will call heightForRow and thus create astack overflow
if(selectedCellIndexPath != nil
&& [selectedCellIndexPathcompare:indexPath] == NSOrderedSame)
return 64;
return 32;
}
I need to create an application that have the same behavior as built-in Reminder App. There are some problems to create this:
Cells that have dynamic height and "grow" as the content of the UITextView
Select the touched cell
Refresh the height of the cell when the user has edited the content(on the fly)
I've already solved the dynamic height, using some trick.
The problem that remains is:
How to know which cell the user has selected if the cell is "fully" with the UITextView ?
Right Now i've used the method textViewDidBeginEditing to know the cell and scroll the UITableView to it:
- (void)textViewDidBeginEditing:(UITextView*)textView
{
MemoViewCell* cell = (MemoViewCell *)[self parentCellFor:textView];
if (cell)
{
NSIndexPath* indexPath = [self.tableView indexPathForCell:cell];
currentIndexPath = indexPath;
[self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
}
}
- (UITableViewCell*)parentCellFor:(UIView*)view
{
if (!view)
return nil;
if ([view isMemberOfClass:[MemoViewCell class]])
return (UITableViewCell*)view;
return [self parentCellFor:view.superview];
}
How to refresh the cell height without lost the focus?
To this, i've used this method:
-(void)textViewDidChange:(UITextView *)textView
{
NSMutableDictionary *dataSourceItem = [self.model.dataSource objectAtIndex:currentIndexPath.row];
[dataSourceItem setObject:textView.text forKeyedSubscript:#"body"];
[self.model.dataSource setObject:dataSourceItem atIndexedSubscript:currentIndexPath.row];
[self.tableView beginUpdates];
[self.tableView endUpdates];
}
When the text change, i get the new text, i change it in the Model and i call beginUpdated and endUpdates.
Sure, this works, but all is extremly slow... do you have some idea to to this in a more elegant way and maybe... efficient?
If i call reloadRowsAtIndexPaths: i lost the focus on the cell.
First of all, if you use the delegate method - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath; in your dynamic height trick, remember to implement this method along - (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath;, it helps a lot in terms of performance.
Then to focus on your specific project, if I correctly understood your goal, what you really want is to update the layout of your table view only when your text view is modified. Currently you're updating it at each text change. You might consider using a condition inside -(void)textViewDidChange:(UITextView *)textView, such as :
if ([textView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height !=
textView.frame.size.height) {
[self.tableView beginUpdates];
[self.tableView endUpdates];
}
The condition given as example will work only if your existing cell layout respects the intrinsic content size of the text view, otherwise you will need to adapt the condition.
I have a tableview. On tap, a cell expands into a form, and I would like the cell to scroll up to start right below the navigation bar. How do I achieve this?
Here's the starting state:
Currently, after tap:
And here's what I want:
You need something like this:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Perform cell change height code here
// ...
// After that scroll to this cell
CGFloat sectionHeaderHeight = [self tableView:tableView heightForHeaderInSection:indexPath.section];
CGRect cellFrame = [tableView rectForRowAtIndexPath:indexPath];
[tableView setContentOffset:CGPointMake(0, cellFrame.origin.y - sectionHeaderHeight) animated:YES];
}
scrollToRowAtIndexPath... or scrollToNearestSelectedRow... both take "scroll position" arguments which allow the selection to go to the top, middle or bottom of the table view. That should give you what you want.
I have a custom tableFooterView (it's just an 8px high CoreGraphics arc with a gradient) that I set with the tableFooterView property in viewDidLoad rather than viewForFooterInSection. When setting it with viewForFooterInSection, it floated over the content when it reached the bottom, whereas tableFooterView does what I want it to in that it stays with the UITableView's height.
But when the cells or table view do change in height, the tableFooterView animates to them slowly (about half a second but it's very noticeable). This is pretty awkward since the footer is supposed to look like an extension of the last cell. For instance, when heightForRowAtIndexPath changes the height of a cell, the tableFooterView kind of ghost-floats back. In this screenshot the bottom cell has just been shrunken to its normal size and the footer is floating back.
(As a new user I can't post images but here's the link: http://desmond.imageshack.us/Himg835/scaled.php?server=835&filename=iossimulatorscreenshotj.png&res=landing)
(This content is no longer available, 14/9/15).
It will also float over the content when the height of the last cell is suddenly changed to be larger than it was.
Any pointers? Thanks very much.
Edit: By cells changing in height, I mean through the heightForRowAtIndexPath section:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
Note *currentNote = [self.notes objectAtIndex:indexPath.row];
if (currentNote.associatedCellIsSelected) {
return NORMAL_CELL_FINISHING_HEIGHT*2;
}
return NORMAL_CELL_FINISHING_HEIGHT;
}
Edit 2: In didSelectRowAtIndexPath I make the cell selected (actually the cell's note), begin / end updates as well as call reloadRow for the row that's been selected.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
Note *currentNote = [self.notes objectAtIndex:indexPath.row];
if (currentNote.associatedCellIsSelected == FALSE) {
currentNote.associatedCellIsSelected = TRUE;
[tableView beginUpdates];
[tableView endUpdates];
}
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; }
I've also made sure that I get the same behavior with a plain rect redColor UIView in place of the Core Graphics footer, with the same results. I wish there was just an easy way to override the footer and tell it to not animate!