Stop a UITableView from automatically scrolling - ios

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.

Related

Why is there no animation while rotating disclosure button?

My button rotates upon clicks in an animated way by using UIView's animateWithDuration:animations:, however the button is not animating.
I'm trying to reimplement UITableView's disclosure indicator. I am making my own because UITableView's is not flexible enough. For example, I would like mine to be on the left, but this is not possible.
My disclosure button subclass almost works. It rotates correctly, but when it rotates there is no animation. It should goes from the non rotated to rotated; there is no animation in between.
#define DegreesToRadians(x) ((x) * M_PI / 180.0)
- (void)rotateToOpenPosition {
[UIView animateWithDuration:0.5 animations:^{
[self setTransform: CGAffineTransformMakeRotation((CGFloat)DegreesToRadians(90))];
}];
}
- (void)rotateToClosedPosition {
[UIView animateWithDuration:0.5 animations:^{
[self setTransform: CGAffineTransformMakeRotation((CGFloat)DegreesToRadians(0))];
}];
}
I'm also using Auto Layout in the nib that contain the UITableViewCell the disclosure button is in.
This might be related to the problem. Here are the constraints:
EDIT: This is most likely not the problem, as I tried removing auto layout from the same nib, and the problem still occurs.
Why is it not rotating, and how can I fix it?
I was calling [tableView reloadData] right after I called the methods to start animating the button.
Stupid.

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!!

UIScrollView Jerky Scrolling

I have a big scroll view. I just wish to scroll around the scroll view with fixed steps on every button press. However when I write the following code the scroll view scrolling is very jaggy. Can someone explain why?
CGPoint lstructCurrentPoint = self.objScrollView.contentOffset;
lstructCurrentPoint.x += 400;
[UIView animateWithDuration:1.0f
delay:0.0f
options:UIViewAnimationOptionCurveLinear
animations:^{
[self.objScrollView scrollRectToVisible:CGRectMake(lstructCurrentPoint.x,
lstructCurrentPoint.y,
self.objScrollView.bounds.size.width,
self.objScrollView.bounds.size.height)
animated:NO];
} completion:^(BOOL finished)
{
}];
I do not use the animated:Yes arguement because I need custom scroll speeds between the different contentOffsets.
when you update your scroolview content frame while scrolling with an animation is like you try to update something that is in the past that is already changed... (probably is not the best explanation :D )
try with this in your animation option:
options:UIViewAnimationOptionCurveLinear|UIViewAnimationOptionBeginFromCurrentState
Why don't you just try using
[self.objScrollView scrollRectToVisible:CGRectMake(lstructCurrentPoint.x, lstructCurrentPoint.y,self.objScrollView.bounds.size.width,self.objScrollView.bounds.size.height) animated:YES];
instead of using this within UIView animation function.
Try to use
[self.objScrollView setContentOffset: CGPointMame(lstructCurrentPoint.x, lstructCurrentPoint.y) animated: YES];
instead of scrollRectToVisible.
scrollRectToVisible animated is an animation by itself.
With your current code, you are trying to animate the animation.
Hence it is jerky.
Just use to scroll the rect to visible:
[self.objScrollView scrollRectToVisible:CGRectMake(lstructCurrentPoint.x,lstructCurrentPoint.y,self.objScrollView.bounds.size.width,self.objScrollView.bounds.size.height) animated:YES];
No one can properly answer your question without knowing what content you have in the scrollView.
However, you can find out what is causing this yourself.
Profile the app on your device. This will open Instruments. Select the Core Animation tool.
When the app is running scroll the view so that instruments captures the data.
Now the Time Profiler section will tell you exactly what is taking a long time. Fix this and you'll have smooth scrolling.

UIScrollView cancel/stop setContentOffset:<CGPoint>animate:YES animation

I have a UIScrollView that I'm scrolling using setContentOffset:animate:YES but if the device rotates I want to be able to stop it. Is this possible? Or how would I go about writing my own implementation of the setContentOffset with animation? thanks!
scrollview.contentOffset = scrollView.contentOffset should stop the scrollView at its last scroll position.
Do this in willAnimateRotationTo..... in your viewController
If you have a UIScrollView sub-class you could do it in setFrame: , this is assuming the frame of the scrollview changes upon orientation change.
try to use this instead:
[UIView animateWithDuration:.25 animations:^
{
// replacement for setContentOffset:animated:
self.scrollView.contentOffset = scrollPositionBeforeKeyboardAdjustments;
}];
if you are struggling with the keyboard, see my answer
How to make a UITextField move up when keyboard is present?

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