2012年3月2日金曜日

iNippon Part 2

The second post about the making of iNippon, the English-Japanese dictionary of conversations about Japan.

More information about the app can be found in iTunes Preview or in the previous blog post.
This time we take a close look at the History page.



Default view, all scrolls closed.
One scroll open.

Usage:
- Tapping a scroll will open it with an animation.
- Tapping an open scroll will close it with an animation.
- Tapping a closed scroll while another scroll is open will first close the open scroll and then open the scroll that was tapped.
- Tapping a historical event will toggle its language between English and Japanese. Of course the height of the text will change and by getting the content height of the UITextView we can tell the UITableView controller of the new row height and with a nice animation adjust the height of that row as well as the y-position of all rows below it (automatically done for us by the UITableView).

The first idea that probably comes to everyones mind is to use a tableview with the scrolls as section headers and each historical event as row in that section (data read from database). At least, that's what I thought would be the natural approach and as a matter of fact, Apple has sample code showing how to implement this and how to make it looks nice with the new animation features in UITableView.

The sample code is called "Table View Animations and Gestures"(Shakespeare plays and citations) and can be found in the iOS Developer Library. If I remember correctly this might also be presented in a WWDC 2010 video which you can access if you are a registered developer.

Problem
There is a problem however with this sample code and how the animations are implemented and I will try to explain to you how to reproduce this.
- Download the sample code and run the app in the simulator.
- Expand the first section header
- Pinch out to make the rows of the first section taller, do this until the second section header disappears out of the bottom part of the screen.
- Scroll down to the second section header and tap it. 

Now the new UITableView animations will animate the closing of the first section and the opening of the second section. This usually looks nice except in this case. If you followed these steps you will see that the animation "flickers", and doesn't look nice at all. Try it with the iPhone simulator's "slow animations"-option and you'll see what's going on. This was totally unacceptable for me and no matter how I tried I could not make this particular case animate in a nice way so I had to scrap this implementation.

Solution
Because I use Core Data and the user can toggle between languages in individual events (which will change the height that item) I wanted to use UITableView to get "free" animations when changing heights. However, I couldn't use it for expanding and contracting sections in a way that would give a good user experience and nice animations. 

What came to be the solution that can be experienced in the app is the following.
For all the headers, that is, the scrolls themselves, I put them in plain UIViews and stack them from top to bottom.

When a user taps a scroll, I load up a customized UITableView which is hidden behind the scroll and then animate it down so it looks like the scroll is being unrolled and the the same adjust the y-position of all the scrolls below so they don't get covered by the opening scroll.

Also, when a user change the language of an individual event the table view will change height and animate automatically, but at this time I also have to adjust the y-position of all scrolls below with the same animation duration as the table view.

When closing a scroll I basically do the opposite. A bunch of animations, all with the same duration makes this look really natural and nice.

So how about the problem that was caused by Apple's implementation. No problem anymore. When a user taps a closed scroll while another scroll is open, I first close the open one and then open the one that was tapped and set the content offset of the outer scroll view so that the opened scroll is at the top of the screen.

Maybe creating a new controller especially for this would had been the most elegant solution but in this case I wanted to save time and reuse the UITableView I already had at hand so the solution became a mix of my own controller for the section headers (scrolls) and a UITableView for the events.

I haven't bothered filing a bug report to Apple about this behavior because if they took the time to create the sample code and properly test it, this malfunctioning animation should have been obvious to them and I doubt a bug report will fix anything if they haven't fixed it earlier. 

However, maybe the best thing to do is to file that bug report anyway...


140 180 iOS

記載されている会社名、および商品名等は、各社の商標または登録商標です。

0 コメント:

コメントを投稿

Related Posts Plugin for WordPress, Blogger...