iPhone - Smooth animation for UITableViewCell height change including content update [duplicate] - iphone

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Can you animate a height change on a UITableViewCell when selected?
I have a table view into which where you click on a swich into a cell, many cells of the table view may change their height. It's a little bit complicated to compute which cells will change their size, so I'd like not to call twice the same code.
I have a heightForRowAtIndexPath method (this is the complicated one).
Is there a way to animate the cell grow or reduce feature without impacting the one that does not change ?
I've tried UIView Animations, reloadData for sections with animation, ... but I didn't find anything smooth.
I've tried to catch each cell that will have to change and call a reloadData with animation on each cell. It's near to work but the cells are updating one after the other. And as I said before, I don't want to do that because I must call twice the heightForRowAtIndexPath method.
What I'd like is something that can animated each cell that has a changing height with somthing like a grow or reduce movement, and not a fade one.
Do you know a way to do that ?
One more thing, the content of the cell is changing a little bit when size change (some text added, back color changing, and things like that)

UITableView has a neat trick to animate changes in cell heights: if you send an empty updates block to the table view, it won't insert or delete any cells, but it will still recalculate cell heights for the entire table. So even though this piece of code looks weird, it should do it:
[tableView beginUpdates];
[tableView endUpdates];
If you want to change the contents of the updated cells, too, you must add one or more calls to reloadRowsAtIndexPaths:withRowAnimation: to the updates block, of course.

Related

How can I replace `UITableViewCell` with a `UIScrollView` or `UITableView` after the main `UITableView` is already loaded?

So I am messing around with how this feels in my app. I have a UITableView and I have the swiping/panning in place, where I kind of flick the cell away and once the cell is away I have it call a method in the same class where I have my UITableView as a property. Once that cell is swiped away and that method gets called, I want to animate the size of the now empty cell to be about 3 times the size of the cell and have a UIScrollView or UITableView be added. It will be a place to store all comments about that cell.
Basically, I would just like some ideas on how I can replace a swiped cell with a UIScrollView or UITableView and animate it to three times the size of any cell.
In a nutshell, if the text below is tl;dr:
call reloadRowsAtIndexPaths, remember which cell you've changed, update cellForRowAtIndexPath and heightForRowAtIndexPath accordingly, and you are set to go.
Full version:
When you said swiped away, did you meant that you are reloading or deleting certain row of your UITableView?
If so, I think you might be able to do what you described by calling [tableView reloadRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationLeft]; (or whatever direction you'd like), then saving the indexPaths you've changed (in your case only one indexPath), and react appropriately in the cellForRowAtIndexPath dataSource method - changing the normal cell for another one, custom-made, with UITableView or UIScrollView inside, and also reacting in the heightForRowAtIndexPath delegate method, to change the height.
The animation itself will be handled by tableView, so that's an ease for you.
Also, if you will use this method to change the contents of the cell for UITableView, don't forget to assign delegate and dataSource of that cell's new tableView, since that causes lot of troubles when forgot.

iPad UITableView flickering issue

I have a UITableView that contain about 20 rows in the iPad's viewport. I have a interval timer that will call UITableView's reloadData regularly(post it to UI thread).
Now when I scroll through the UITableView with medium speed (not so fast), that UITableView will refresh with flickering effect.
I have to write a function to manually update the UITableViewCell label by looping through all the items in the array (this array keep all the items that show on UITableView). I will execute this function when timer is running instead of calling reloadData (as I mentioned above). Then the flickering issue is gone.
I believe that reloadData should be better than looping through all the data because reloadData will only refresh the current showing Cells instead of all the rows, but I couldn't figure out why the flickering happens. Anyone know why?
One thing I have to mention is I did use the CellIdentifier correctly to reuse the cell and only create the cell when the retrieved cell is null.
Moreover, I do not have this issue in iPhone and I believe that it is because iPhone has lesser row compare to iPad.
Anyone can give some explanation about this issue?
I had the same problem with flickering when using reloadData. I solved it by using indexPathsForVisibleRows and cellForRowAtIndexPath: to only update the visible cells. Performance is good since I don't have to iterate over the whole data set, but only a limited number of visible cells.
reloadData causes the tableview to recreate the visible cells on screen which can result in a flickering since the cells get destroyed. There are better ways to reload the tableview. Are you using Core Data? If so the NSFetchedResultsController and it's delegate are a great way to update a tableview since it listens to changes in the underlying datasource and only updates the appropriate cells.

Expanding UITableViewCell on Tap?

I need to expand a UITableView cell when I tap it (animate it as well). However I don't know the cell which is being tapped and I have seen the answer here: Can you animate a height change on a UITableViewCell when selected?
It seems to be a very popular answer, not just in the question. However, I need to get the cell, so how in the heightForRowAtIndexPath method can I get the cell?
Because I have tried this:
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
However using this in the heightForRowAtIndexPath method crashes the app as the first time it runs (when the view loads) it gets caught in an infinite loop I think.
Anyway if I was to take this approach how would you suggest i get around this issue? I need to access the cell. Or how else would you expand your tableview cell (animated)?
Carry on adjusting the height as you are.
I would suggest trying to get as much as you can from autoresizing masks as they have worked well for me in the past.
If you need finer grained control you can create a subclass and override the setFrame: method to find out when the frame is changing size and then set up animations appropriately there.

Displaying dynamic subview in tableviewcell

After the user taps a tableview cell, I'd like to slide open a small view just below the cell . The first screenshot of these two apps show this:
Tweetie 2: http://itunes.apple.com/us/app/tweetie-2/id333903271?mt=8
Pastebot: http://itunes.apple.com/us/app/id344614116?mt=8
I know how to dynamically increase the height of a cell but that is a different effect than the above. The slide out view affect doesn't seem to increase the cell's height. Also, the new view isn't as wide. Any suggestions on how to go about designing that?
You could create and insert, with animation, a new custom cell under it. Check out insertRowsAtIndexPaths:withRowAnimation:.
UPDATE
I also really like your idea of using a "slideout" view, but I agree with TechZen that this should be added as a subview of the cell.
If you want to increase the height of the cell, you need to return the correct heights for all the cells from the delegate method tableView:heightForRowAtIndexPath:. You will need to return the same height (standard is 44) for all rows except the one with the extra view which will be increased by the height of the new view.
I don't think they're sliding a view beneath the cell view, I think they're inserting the view into the cell itself and modifying the graphics to create the illusion of an overlying view.
I don't really know how they did that, but in the last minutes I tried some experiments and... the easiest solution is definitely:
NSIndexPath *myIndexPath = [NSIndexPath indexPathForRow:[selectedCell intValue]+1 inSection:0];
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:myIndexPath] withRowAnimation:UITableViewRowAnimationTop];
Insert some custom graphics (cellForRowAtIndexPath) and it looks quite the same.
Those two apps are doing things that are quite different. Tweetie is overlaying a new cell on top of an existing one, while PasteBot is creating a new one underneath, and animating the expansion of the table view. Mooch! does the same thing as PasteBot, and it's a really cool effect that I'd like to duplicate.

Is it possible to resize a UITableViewCell without using UITableViewDelegate?

I want to resize my table view cells from inside the cell instead of from the UITableViewDelegate. I am resizing them based on asynchronous content, so I can't size them in the delegate.
I tried setting self.frame inside the cell, but the table view was really unhappy about that. Cells were overlapping and all kinds of craziness was going on.
You simply have to use the table view to control height. You can tell the table a cell has altered by using the calls to remove and then re-add specific cells, so you don't have to reload the whole table - but the height has to be fetched using the delegate callback tableView:heightForRow:atIndexPath:
I don't see why this is not practical though. You can have any number of asynch systems running that update a central height cache held by the table view delegate - every time you create a cell you can assign it the delegate as a reference so it has a way to talk back to the table and let it know cells need reloading and what the new heights are.
If you think about it, the poor table view is a scroll view that has to manage all these separate cells and keep them together visually - so it's really unkind of a cell to go rogue and start altering frames without letting the table view know what is going on anyway. It's best to let the table drive and tell it what to do.
No you can not set the cell's size without using the UITableViewDelegate. Changing the size of the cell with actually change the size of the cell, but it will not change the offsets that the UITableView draws the cells with. Which will result in overlaps, and gaps all over the place.
Your friend is tableView:heightForRowAtIndexPath:, and it should be fast. If you override it, then the table view can no longer make the assumption that all rows are of the same height. And thus it must query all rows for their height each time it fetches cells to draw.
You should try to manage the cells contentView propertys frame, instead of the cells frame itself
heres a reference http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableViewCell_Class/Reference/Reference.html#//apple_ref/occ/instp/UITableViewCell/contentView