Animating UITableView resize - ios

Im using the following code to animate the resizing of a UITableView to make way for a UIView with extra controls when the UITableView.isEditing.
[UIView animateWithDuration:3 // 0.2 but slowed down to easily see difference
delay:0
options:UIViewAnimationOptionCurveEaseOut
animations:^{
[self.selectControlsView setFrame:CGRectMake(0, self.tableView.frame.size.height-self.selectControlsView.frame.size.height, self.selectControlsView.frame.size.width, self.selectControlsView.frame.size.height)];
[self.tableView setFrame:CGRectMake(0, 0, self.tableView.frame.size.width, self.tableView.frame.size.height-self.selectControlsView.frame.size.height)];
}
completion:nil];
This works fine except it seems the UITableView animates faster than the UIView does (even though I adjust the UIViews frame before the UITableViews frame), causing a black flicker during the animation from the background.
Is there a way to animate the two views in tandem?

The problem was caused because the controller was a subclass of UITableViewController. I'm now subclassing UIViewController and adding the UITableView as a subview, the animation for adding the new view and resizing the UITableView now works as expected.

Related

Stop a UITableView from automatically scrolling

I have a UITableView that I'm autoscrolling with setContentOffset. Like so:
CGFloat point = self.table.tblMinutes.contentSize.height - self.table.tblMinutes.bounds.size.height;
[self.table.tblMinutes setContentOffset:CGPointMake(0, point) animated:false];
[self.table.tblMinutes layoutIfNeeded];
[UIView animateWithDuration:20.0 delay:0 options:UIViewAnimationOptionCurveLinear animations:^{
[self.table.tblMinutes setContentOffset:CGPointMake(0, point - 500) animated:false];
} completion:nil];
What I want to achieve is for the scrolling to smoothly slow down and stop. I haven't been able to achieve that.
Calling [self.table.tblMinutes.layer removeAllAnimations] stops the animation, but moves the contentOffset for some reason, not achieving what I want.
I tried using the UIViewAnimationOptionBeginFromCurrentState option in a animation but that did nothing.
Any suggestions?
This is a subset of the classic problem of interrupting an existing animation and replacing it with a different animation.
The problem here is that if you merely remove the existing animation, you will jump to the end of that animation.
The solution to that is to consult the presentation layer and set the layer to that position before removing the existing animation. Now you are starting from midstream and can apply another animation.
Take a look at Kyle Truscott's excellent blog post about this for UIScrollView. UITableView inherits from UIScrollView, so in theory, it should work.

How to translate an entire UIView and retain gesture recognition?

I have a UIView "MainView" that initially appears as follows:
The gradient bar is part of MainView, the whitespace beneath is part of a Container View subview.
When the search button in top-right is tapped, I animate a searchBar from offscreen to be visible in the view:
I manage to do this by the following code:
CGRect currentViewFrame = self.view.bounds;
currentViewFrame.origin.y += searchViewHeight;
[UIView animateWithDuration:0.4
delay:0.0
usingSpringWithDamping:1.0
initialSpringVelocity:4.0
options:UIViewAnimationOptionCurveEaseInOut animations:^{
self.view.frame = currentViewFrame;
}
completion:^(BOOL finished)
{
}];
Visually, the result of this animation is perfect. The entire view shifts, and the searchBar is now on screen. However, the searchBar does not respond to interaction. Correct me if I'm wrong, but I expect this is because the MainView's frame no longer includes the screen area that the searchBar now occupies, so its effectively a gesture deadzone.
So this makes me think that instead of lazily animating the entire MainView down to accomodate the searchBar, I must instead individually translate all subviews of MainView one at a time. In this simple situation, that would not be a big problem, but I can envision a circumstance with tens of subviews making that completely unrealistic.
What is the best method to accomplish what I am trying to do? Is there a secret to animating entire views/subviews without having gesture deadzones? Thanks in advance!!

Leveled UITableView without NavigationController

I have data structured as a tree (and showed in UITableView) and I would like to show it the way it is usually done using UINavigationController and pushing child views on to the stack. The problem is that my UITableView (in an iPad app) takes only 1/6 of the screen (there is a UINavigationController that handles other fullscreen iPad screens in this app, so using NavigationController to control the levels of table is the good way).
Is there a simple way to get a good visual effect of changing the levels of TableView without using NavigationController? Right now I just change the data source and reload data, but that does something like a flicker on the screen (the user can't really see, that the structure of the data is tree-like).
I thought of creating a few TableViews and then just animating the resize (from full width to 0 the TableView that we are leaving, and from 0 to width at the same time of the another one) of a table just to make something like segue effect - but I am not sure if this is a good approach.
You can use reloadSections:withRowAnimation: with UITableViewRowAnimationLeft and UITableViewRowAnimationRight instead of a default reloadData. This will look like the push you are looking for.
Reference: http://developer.apple.com/library/ios/documentation/uikit/reference/UITableView_Class/Reference/Reference.html#//apple_ref/occ/instm/UITableView/reloadSections:withRowAnimation:
You can try this code (after you set the proper values:))
__block CGRect frame = tableView.frame;
[UIView animateWithDuration:0.5 animations:^{
frame.origin.x -=tableView.frame.size.width;
} completion:^(BOOL finished) {
frame.origin.x = yourViewThatContainsTheTable.frame.size.width
tableView.frame = frame;
[tableView reloadData];
[UIView animateWithDuration:0.3 animations:^{
frame.origin.x = 0;
tableView.frame = frame;
}];
}];
Basically if you are using subclasses of UIView you can use [UIView animateWith...] methods to perform simple animations or you can use CAAnimations/CABasicAnimation/CAAnimationGroup/CAKeyframeAnimation for more complex animations on subclasses of UIView.
If you want a custom transition for a UIViewController you can use CATransition.

Animating two UIView subviews at the same time does not work

For some reason i am not able two animate two subviews postion. I have wrote the following
[self addChildViewController:self.photosViewController];
[self.photosViewController.view setFrame:CGRectMake(0, -self.view.frame.size.height, self.view.frame.size.width, self.view.frame.size.height)];
[self.view addSubview:self.photosViewController.view];
[UIView animateWithDuration:1 delay:0
options:UIViewAnimationOptionCurveEaseIn
animations:^{
[self.stepsView setFrame:CGRectMake(0, self.view.frame.size.height, self.view.frame.size.width, self.view.frame.size.height)];
[self.photosViewController.view setFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
}
completion:^(BOOL finished) {
if (finished) {
button.tag = 0;
}
}];
self.stepsView is an IBOutlet UIView and self.photosViewController.view is an child view controllers view that has been added to the view.
With the current code only the self.PhotosViewController.view animates. However if i comment out the line where i add the child view controllers view as a subview then the self.stepsView animates correctly.
Even if i add the child view controller and its view before this method is called the same error happens.
Need help as i ran in to this a couple of months back with another app and had to do a dirty hack to get around it and now want to solve this.
Thanks
In the section on view animation in the View Programming Guide there is a specific mention of how to animate subviews.
Basically, you should use transitionWithView:duration:options:animations:completion: rather than animateWithDuration:delay:options:animations:completion:.
The first view will not be visible, because its origin.y is beyond the height of the visible view. If it was not visible when the animation starts, you will of course see nothing.
The second view is changed to fill the screen. Again, what you see depends on its initial position.

UIView animation while scrolling a table

I have a UITableView in an iPad, and its right half side is covered with a view.
What I want is: when the user scroll the UITableView, I want the covering view to slide (with an animation) to the right until its origin.x is at the end of the right side of the table, so the UITableView is clear to see (just like in the Twitter app for iPad).
The problem is: You can scroll the UITableView and animate a view at the same time. When I start scrolling, I use didStartDraging and even DidScroll to create a [UIView animate...] method, but this method stuck my scrolling.
I tired with block animation. I tried with Gestures. I tried with CABasicAnimation, and it goes quite OK, but somehow all the UISubview "Touch area" in my sliding view stay at the old place (what I mean is that the view gets its new frame, but I can scroll a UIScrollView, which is a UISubview of my view, even when my finger is out of the superviews frame S-:, even that there is no view at that point on screen.)
Any thoughts how can I make the animation without damaging the scroll of the table? (and I heard about the timer in the K and the runloop common modes. Not so helping)
Thanks.
scrollview Delegate methods will be invoked for tableView also ............
you can use following code it worked for me and hope will work for you also.......
-(void)scrollViewDidScroll:(UIScrollView *)scrollView
{
[UIView animateWithDuration:0.3 animations:^{
[scrollView setFrame:CGRectMake(50, scrollView.frame.origin.y, scrollView.frame.size.width, scrollView.frame.size.height)];
}];
}
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
[UIView animateWithDuration:0.3 animations:^{
[scrollView setFrame:CGRectMake(100, scrollView.frame.origin.y, scrollView.frame.size.width, scrollView.frame.size.height)];
}];
}
set x position of scrollView(tableView) as your requirement......
Have a happy coding....

Resources