Detect "end decelerating" in a programmatically moved scrollview - iphone

I had a manually dragged scrollview, now I want a scrollview moved programmatically when I click a button, by this code:
offset = CGPointMake(scrollView.contentOffset.x+320, 0);
[UIScrollView beginAnimations:#"scrollAnimation" context:nil];
[UIScrollView setAnimationDuration:0.5];
[scrollView1 setContentOffset:offset];
[UIScrollView commitAnimations];
It works well but now the functions scrollViewBeginDragging and scrollViewEndDecelerating are not called. Begindragging is no problem for me, but I don't know how detect the end of de scrollview movement when it is fired programmatically.
Thanks in advance!

Implement the scrollViewDidEndScrollingAnimation: delegate method. That's exactly what it's for.

Well... you kind of know when that's supposed to get called, right? Those callbacks are intended for touches, so they won't work, but you're telling it to finish 0.5, so why not schedule a call to the delegate method yourself?
[self performSelector:#selector(scrollViewDidEndDecelerating:) withObject:scrollView afterDelay:0.5];

Related

scrollViewWillEndDraggin:WithVelocity:targetContentOffset delegate method bug

I am implementing a UIScrollView and its delegate in a UIViewController. It scrolls in the horiztonal way.
WHat I want is to set "magnetism" when the view is dragged and is stabilizing.
to do that, I am listening to the delegate, specially the method mentionned in titled.
It returns me the offset of the final destination.
then I make the scollview display the view which correspond to this destionation with setContentOffset or setvisiblerect methods.
I also NSlog the entire method to catch the bugs.specially right after calling the method I have a nslog which confirmed me/or not, if the method is triggered.
problem : when I build&run, the first nslog is triggered an average of 3 times by dragging.
so the entire effect looks very strange and I can't figure out whether or not it works.
I have found very little things about this on the net. So it would be a great help if you had some clues.
cheers
I am kind of desperate :/
So you want the scroll view to snap to a valid selection when the user is done dragging? You should be able to implement this using the
- (void)scrollViewWillBeginDragging:(UIScrollView *)thisScrollView
and
- (void)scrollViewWillDidScroll:(UIScrollView *)thisScrollView
methods. Without seeing your code I can't tell you exactly how to go about this, but I would recommend keeping track of the thisScrollView.contentOffset.x in a variable, and doing some arithmetic to move the scrollView with a
[UIView beginAnimations: #"anim" context: nil];
[UIView setAnimationBeginsFromCurrentState: YES];
[UIView setAnimationDuration: movementDuration];
self.view.frame = CGRectOffset(self.view.frame, 0, movement);
[UIView commitAnimations];
call to move it to the appropriate spot.

Animation is effecting every view even after calling commitAnimation

I am developing a Cocos2D game. On a stage a show a UIView giving users a list of tasks to perform. There are text fields which I move up or down using Animation. My code is below.
[textField setFrame:CGRectMake(textField.frame.origin.x, textField.frame.origin.y, textField.frame.size.width, textField.frame.size.height)];
[inviteButton setFrame:CGRectMake(inviteButton.frame.origin.x, inviteButton.frame.origin.y, inviteButton.frame.size.width, inviteButton.frame.size.height)];
[headingLabel setFrame:CGRectMake(headingLabel.frame.origin.x, headingLabel.frame.origin.y, headingLabel.frame.size.width, headingLabel.frame.size.height)];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];
[UIView setAnimationDelegate:self];
[textField setFrame:CGRectMake(textField.frame.origin.x, textField.frame.origin.y-50, textField.frame.size.width, textField.frame.size.height)];
[inviteButton setFrame:CGRectMake(inviteButton.frame.origin.x, inviteButton.frame.origin.y-50, inviteButton.frame.size.width, inviteButton.frame.size.height)];
[headingLabel setFrame:CGRectMake(headingLabel.frame.origin.x, headingLabel.frame.origin.y-30, headingLabel.frame.size.width, headingLabel.frame.size.height)];
[UIView commitAnimations];
[self.view.layer removeAllAnimations];
Problem is that even after user is done and he presses the cancel button to remove this view from the super view, every view including UIAlertView and other subviews appearing in my map after removing that view are effected by the animation i used to move text fields and label up or down. UIAlertView is using same Animation to show up and so is happening other subviews. Can anyone please tell me why this is happening?
Best Regards
You have to set the animationID to a unique value in the beginAnimations:context: method.
See the official doc
Also this doc states:
Use of this method is discouraged in iOS 4.0 and later. You should use the block-based animation methods to specify your animations instead.

iOS views animation

I am trying to create an animation for switching views on iOS devices.
I have create an application with three views and I have some navigation buttons.
The way I use to switch views is this:
-(IBAction) loadThirdView:(id)sender {
[self clearView];
self.thirdViewController.view.frame = CGRectMake(0, 208, 160, 208);
[self.view insertSubview:thirdViewController.view atIndex:0];
}
As you can see this is the action that takes place once I press the button. What I would like is the new view to appear in an animated way.
Specifically I want it to start from the left hand side of the screen and slide to the right. I do not want it just to appear.
Is this possible? how can I do it?
Oh no! Ah, no! Please do not display UIViewControllers this way.
Present your UIViewController this way:
[self presentModalViewController:self.thirdViewController animated:YES]
Before presenting it, you can change the modalTransitionStyle property of the view controller to suit your needs.
If using a UINavigationController, use instead:
[yourNavController pushModalViewController:self.thirdViewController animated:YES]
This is a nice little article (if not a little too harsh): Abusing UIViewControllers
To animate it the way you specifically would like (as the UINavigationController style is sliding in from the right), you might want to use something like what is proposed in this SO question: iPhone Pushing View Controller in a left direction
You can try
[UIView transitionFromView:currView toView:nextView duration:0.5f options:UIViewAnimationOptionTransitionFlipFromLeft completion:nil];
if you want different type of animation. There're lots AnimationsOptions you can choose, just set the options:.
Sample Code :
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:0.6];
yourImageVieew.alpha=0.9;//insert here what you want
[UIView commitAnimations];

Is it possible to change UIView's "center" property inside the overriden touchesEnded method and redraw the view?

I want to implement a simple animation based on UIView's center property. I have a simple view and I can drag it (UIView touchesMoved is overriden). The animation should fade slowly like the view is moved under it's own inertia for some time after the user releases it. But for now I want simply to move the view after touch ends. Here is the code I have in touchesEnded:
int i;
for (i=1;i<4;i++)
{
self.center = CGPointMake(10*i, 12*i);
[self setNeedsDisplay];
usleep(100000);
}
The problem is when I run this, the code is executed nicely but "UIView" changes to late. I changed usleep time and other parameters but the result is the same. It looks like all the "pending changes" in the view are performed only after the overriden touchesEnded is finished.
Is this the right way of implementing such user interface feature or should I look for some other approaches?
Thanks in advance.
If you know the final positions you want your view center to have you could do this with an animation:
[UIView animateWithDuration:20
delay:0
options: UIViewAnimationOptionCurveEaseIn
animations:^{
youView.center = CGPointMake(newCenterX, newCenterY);
}
completion:^(BOOL finished){
}];
If that code is being run inside of touchesEnded you are blocking the main thread and that is why the animation happens all at once when its done. You will need run this loop in the background to update the view over time. When you update the UI remember to always call back to the main thread.
Some Threading Options:
performSelectorInBackground:withObject:
performSelectorOnMainThread:withObject:waitUntilDone:
Grand Central Dispatch
Threading

Always animate UIView to user's tap location

I have a UIView that I want to animate to the position where the user's finger currently is.
So, when the touch begins, it has to animate to the tap location.
When the touch moves, it has to adjust its destination to the new location.
When the touch ends, it has to finish the animation to the last tap location.
I tried several things but none worked out. I tried creating a new animation with beginsFromCurrentState in touchesMoved, but that didn't work too.
It seems you're complicating this a little bit. If you are implementing touchesMoved, you are wanting a drag. If you are more interested in a tap, then touchesEnded is where you want to implement this. Either way, you just need to get the location in view and update your UIView's center based upon that location. If you wrap the change to the center value in a UIView animation block, it will animate to the position as it updates.
If you are using iOS 3.2 or later, you can use gesture recognizers which makes this pretty trivial:
// In viewDidLoad or some such
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc]
initWithTarget:self action:#selector(viewWasTapped:)];
[[self view] addGestureRecognizer:tapRecognizer];
Then declare your action selector:
- (void)viewWasTapped:(UITapGestureRecognizer*)recognizer
{
CGPoint location = [recognizer locationInView:[self view]];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1.0f]; // take a second to animate
[viewToMove setCenter:location];
[UIView commitAnimations];
}
This will animate the view from one location to another. This is referred to as implicit animation. Using Core Animation classes such CAKeyframeAnimation or CABasciAnimation would be explicit animation.
Need a few more details for this.. But are you sure you are using touchesBegan, touchesMoved and touchesEnded from the appropriate view (ie not the view you want to move)? Also make sure the userInteractionEnabled = YES. Try logging the touches from touchesBegan to make sure you are receiving the touches.
Or you might want to just check out Apples MoveMe sample code at https://developer.apple.com/library/ios/#samplecode/MoveMe/Introduction/Intro.html where they have solved all those problems for you.