Custom animation when hiding UINavigationBar - objective-c

I'm making an application which shows/hides (in custom animation) the UINavigationBar on single tap.
I have created two functions (one for showing and the other for hiding). The function for showing the UINavigationBar works perfectly:
- (void) showNavigationBar {
[UINavigationBar beginAnimations:#"NavBarFadeIn" context:nil];
self.navigationController.navigationBar.alpha = 0;
[UINavigationBar setAnimationCurve:UIViewAnimationCurveEaseIn];
[UINavigationBar setAnimationDuration:0.5];
[UINavigationBar setAnimationTransition:UIViewAnimationOptionTransitionFlipFromTop
forView:self.navigationController.navigationBar
cache:YES];
self.navigationController.navigationBar.alpha = 1;
[UINavigationBar commitAnimations];
}
But the function for hiding it, even if it's the same, doesn't work. The UINavigationBar disappears suddenly with no animation.
- (void) hideNavigationBar {
[UINavigationBar beginAnimations:#"NavBarFadeOut" context:nil];
self.navigationController.navigationBar.alpha = 1;
[UINavigationBar setAnimationCurve:UIViewAnimationCurveEaseIn];
[UINavigationBar setAnimationDuration:0.5];
[UINavigationBar setAnimationTransition:UIViewAnimationOptionTransitionCurlUp
forView:self.navigationController.navigationBar
cache:YES];
self.navigationController.navigationBar.alpha = 0;
[self.navigationController setNavigationBarHidden:YES animated:NO];
[UINavigationBar commitAnimations];
}
The calling:
- (void)contentView:(ReaderContentView *)contentView touchesBegan:(NSSet *)touches
{
if( [[self navigationController] isNavigationBarHidden] == NO)
{
if (touches.count == 1) // Single touches only
{
UITouch *touch = [touches anyObject]; // Touch info
CGPoint point = [touch locationInView:self.view]; // Touch location
CGRect areaRect = CGRectInset(self.view.bounds, TAP_AREA_SIZE, TAP_AREA_SIZE);
if (CGRectContainsPoint(areaRect, point) == false) return;
}
[mainToolbar hideToolbar];
[mainPagebar hidePagebar]; // Hide
[self hideNavigationBar];
lastHideTime = [NSDate new];
}
}
Anybody has a clue about why this is happening?

It is happening, because you are calling [self.navigationController setNavigationBarHidden:YES animated:NO]; in the animation code but boolian values are not animatable. There is no "in between values" for bool values.
You should call [self.navigationController setNavigationBarHidden:YES animated:NO]; in a method which you schedule after the animation with
[UINavigationBar setAnimationDidStopSelector: #selector(myCoolMethod:)];

Related

Hide UINavBar and UITabBar at the same time with animation

Edit: I awarded the bounty to john since he put a lot of effort into his answer, and would get it anyways, but there's still no working solution. I am still looking for an answer, if someone knows how to do this it'd be greatly appreciated.
I want to add a "maximize" button to my app that hides the navigation and tab bar. The navbar and tabbar should slide in/out smoothly, and the inner/content view should also expand and shrink at the same rate as the navbar and tabbar.
I used [self.navigationController setNavigationBarHidden: YES/NO animated: YES]; for the navbar and found this thread How to hide uitabbarcontroller for hiding the tabbar.
UITabBar class extension:
- (void) setTabBarHidden:(BOOL)hidden animated:(BOOL)animated {
CGRect screenRect = [[UIScreen mainScreen] bounds];
float screenHeight = screenRect.size.height;
if (UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation)) {
screenHeight = screenRect.size.width;
}
if (!hidden) {
screenHeight -= self.tabBar.frame.size.height;
}
[UIView animateWithDuration: (animated ? UINavigationControllerHideShowBarDuration : 0) animations: ^{
for (UIView* each in self.view.subviews) {
if (each == self.tabBar) {
[each setFrame: CGRectMake(each.frame.origin.x, screenHeight, each.frame.size.width, each.frame.size.height)];
} else {
[each setFrame: CGRectMake(each.frame.origin.x, each.frame.origin.y, each.frame.size.width, screenHeight)];
}
}
} completion: ^(BOOL finished) {
NSLog(#"Animation finished %d", finished);
}];
}
The problem is when I use the two at the same time (hiding/showing the nav and tab bar), it's not clean. If the navbar comes first, anything anchored to the bottom jumps (see example below), and if the tabbar comes first, the top jumps.
Example: I position the UIButton in the bottom right and set its autoresizing mask
resizeButton.frame = CGRectMake(self.view.bounds.size.width - 50, self.view.bounds.size.height - 100, 32, 32); // hardcoded just for testing purposes
resizeButton.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin;
But when the navbar and tabbar are minimized the UIButton jumps between the two states (doesn't slide along with the tab bar). However, if I change it to attach to the top right, it slides perfectly with the nav bar.
Does anyone know how to solve this?
Edit:
This is the closet and most elegant solution I have so far (just trying to get a working concept):
[UIView animateWithDuration: UINavigationControllerHideShowBarDuration animations: ^{
if (self.isMaximized) {
self.tabBarController.view.frame = CGRectMake(0, 20, screenRect.size.width, screenRect.size.height + 49 - 20);
[self.navigationController setNavigationBarHidden:YES animated:YES];
} else {
self.tabBarController.view.frame = CGRectMake(0, 20, screenRect.size.width, screenRect.size.height - 20);
[self.navigationController setNavigationBarHidden:NO animated:YES];
}
} completion: ^(BOOL finished) {
NSLog(#"Frame done: %#", NSStringFromCGRect(self.view.frame));
return;
}];
On maximizing:
Slides the navbar up, and slides the tabbar down, at the same time
The top of the inner/content view slides up, and the bottom of this view jumps down
On minimizing:
Slides the navbar down, and slides the tabbar up, at the same time
The top of the inner/content view slides down properly, but the bottom jumps to the final value, leaving whitespace which is then covered by the sliding tabbar
If I rearange the order of the minimizing-animations (so the navbar animatino is called first), then the top in the inner/content view jumps
the solution i use should eliminate the jump problem you see.
this solution is derived from an Objective-C category found Carlos Oliva's github page, and while the copyright in that code is "all rights reserved", i wrote him and he provided permission for use.
my category code varies only slightly from his code. also, find below the category code the invocation code that i use in my app.
from UITabBarController+HideTabBar.m
// the self.view.frame.size.height can't be used directly in isTabBarHidden or
// in setTabBarHidden:animated: because the value may be the rect with a transform.
//
// further, an attempt to use CGSizeApplyAffineTransform() doesn't work because the
// value can produce a negative height.
// cf. http://lists.apple.com/archives/quartz-dev/2007/Aug/msg00047.html
//
// the crux is that CGRects are normalized, CGSizes are not.
- (BOOL)isTabBarHidden {
CGRect viewFrame = CGRectApplyAffineTransform(self.view.frame, self.view.transform);
CGRect tabBarFrame = self.tabBar.frame;
return tabBarFrame.origin.y >= viewFrame.size.height;
}
- (void)setTabBarHidden:(BOOL)hidden {
[self setTabBarHidden:hidden animated:NO];
}
- (void)setTabBarHidden:(BOOL)hidden animated:(BOOL)animated {
BOOL isHidden = self.tabBarHidden;
if (hidden == isHidden)
return;
UIView* transitionView = [self.view.subviews objectAtIndex:0];
if (!transitionView)
{
#if DEBUG
NSLog(#"could not get the container view!");
#endif
return;
}
CGRect viewFrame = CGRectApplyAffineTransform(self.view.frame, self.view.transform);
CGRect tabBarFrame = self.tabBar.frame;
CGRect containerFrame = transitionView.frame;
tabBarFrame.origin.y = viewFrame.size.height - (hidden ? 0 : tabBarFrame.size.height);
containerFrame.size.height = viewFrame.size.height - (hidden ? 0 : tabBarFrame.size.height);
[UIView animateWithDuration:kAnimationDuration
animations:^{
self.tabBar.frame = tabBarFrame;
transitionView.frame = containerFrame;
}
];
}
from my ScrollableDetailImageViewController.m
- (void)setBarsHidden:(BOOL)hidden animated:(BOOL)animated
{
[self setTabBarHidden:hidden animated:animated];
[self setStatusBarHidden:hidden animated:animated];
// must be performed after hiding/showing of statusBar
[self.navigationController setNavigationBarHidden:hidden animated:animated];
}
- (void)setTabBarHidden:(BOOL)hidden animated:(BOOL)animated
{
id parent = self.navigationController.parentViewController;
if ([parent respondsToSelector:#selector(isTabBarHidden)]
&& hidden != [parent isTabBarHidden]
&& [parent respondsToSelector:#selector(setTabBarHidden:animated:)])
[parent setTabBarHidden:hidden animated:animated];
}
Just try this code, If it is working. I have written this code a year before. But, still it works good for me.
I didn't used the block based animations. Because it was written when I am new to iOS. Just try and optimize yourself as you wanted.
- (void) hideTabBar:(UITabBarController *) tabbarcontroller {
[self.navigationController setNavigationBarHidden:YES animated:YES];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.1];
for(UIView *view in tabbarcontroller.view.subviews)
{
if ([[UIDevice currentDevice]userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
if([view isKindOfClass:[UITabBar class]])
{
[view setFrame:CGRectMake(view.frame.origin.x, 480, view.frame.size.width, view.frame.size.height)];
}
else
{
[view setFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, 480)];
}
}else if([[UIDevice currentDevice]userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
if([view isKindOfClass:[UITabBar class]])
{
[view setFrame:CGRectMake(view.frame.origin.x, 1024, view.frame.size.width, view.frame.size.height)];
}
else
{
[view setFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, 1024)];
}
}
}
[UIView commitAnimations];
}
// Method shows the bottom and top bars
- (void) showTabBar:(UITabBarController *) tabbarcontroller {
[self.navigationController setNavigationBarHidden:NO animated:YES];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.1];
for(UIView *view in tabbarcontroller.view.subviews)
{
if ([[UIDevice currentDevice]userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
if([view isKindOfClass:[UITabBar class]])
{
[view setFrame:CGRectMake(view.frame.origin.x, 430, view.frame.size.width, view.frame.size.height)];
}
else
{
[view setFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, 436)];
}
}else if([[UIDevice currentDevice]userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
if([view isKindOfClass:[UITabBar class]])
{
[view setFrame:CGRectMake(view.frame.origin.x, 975, view.frame.size.width, view.frame.size.height)];
}
else
{
[view setFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, 980)];
}
}
}
[UIView commitAnimations];
}
Try this
you can hide tabbar contrller and navigation bar using animation like:-
-(IBAction)hide:(id)sender
{
[self hideShowBars];
}
- (void) hideShowBars
{
CGRect rect = self.navigationController.navigationBar.frame;
CGRect rect1 = self.tabBarController.tabBar.frame;
if(self.navigationController.navigationBar.isHidden)
{
[self.navigationController.navigationBar setHidden:NO];
rect.origin.y=self.view.frame.origin.y;
}
else
{
rect.origin.y=self.view.frame.origin.y-rect.size.height;
}
if(self.tabBarController.tabBar.isHidden)
{
[self.tabBarController.tabBar setHidden:NO];
rect1.origin.y=self.view.frame.size.height-rect1.size.height-rect1.size.height;
}
else
{
rect1.origin.y=self.view.frame.size.height;
}
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.50];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(hideShowBarsAnimationStopped)];
self.navigationController.navigationBar.frame=rect;
self.tabBarController.tabBar.frame = rect1;
[UIView commitAnimations];
}
- (void) hideShowBarsAnimationStopped
{
if(self.navigationController.navigationBar.frame.origin.y==self.view.frame.origin.y)
return;
if(!self.navigationController.navigationBar.isHidden)
{
[self.navigationController.navigationBar setHidden:YES];
}
if(!self.tabBarController.tabBar.isHidden)
{
[self.tabBarController.tabBar setHidden:YES];
}
}

"Drag 'n' Drop" game animation

I'm quite new to Objective-C and am looking to create a fairly simple Jigsaw. I'm currently just looking at making a 4-piece puzzle as a way of learning the method.
At the moment I have 4 pieces placed around the screen that when dragged to a specific place on screen, snap to that place.
My problem is trying to animate the touches. I want the image touched to expand a little but i'm having trouble with the syntax. I've looked at the MoveMe example that Apple provide but it's not helping me in this situation. Below is the code. I'd appreciate any help with this. Thanks.
-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
//location of current touch
CGPoint location = [touch locationInView:self.view];
if ([touch view] == image1) {
image1.center = location;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
image1.transform = CGAffineTransformMakeScale(1.5, 1.5);
[UIView commitAnimations];
} else if ([touch view] == image2) {
image2.center = location;
animateFirstTouch:image2;
} else if ([touch view] == image3) {
image3.center = location;
image3.transform = CGAffineTransformMakeScale(1.5, 1.5);
} else if ([touch view] == image4) {
image4.center = location;
image4.transform = CGAffineTransformMakeScale(1.5, 1.5);
}
}
-(void) animateFirstTouch:(UIView *)image {
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
self.view.transform = CGAffineTransformMakeScale(1.5, 1.5);
[UIView commitAnimations];
}
The code for image1 works, and the image is scaled up over 0.5 seconds.
The code for image2 throws up an error: expression result unused for animateFirstTouch:image2.
The code for image3 and image4 scales up the images without the animation.
Refer to Kuldeep's answer from this link. I think that would work for you:
iPhone/iOS: How to implement Drag and Drop for subviews of a Scrollview?
Also as an alternative refer to iPhone's answer in this link:
iPhone App: implementation of Drag and drop images in UIView
-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
//location of current touch
CGPoint location = [touch locationInView:self.view];
if ([touch view] == image1) {
[self animateFirstTouch:image1 withLocation:location];
} else if ([touch view] == image2) {
[self animateFirstTouch:image2 withLocation:location];
} else if ([touch view] == image3) {
[self animateFirstTouch:image3 withLocation:location];
} else if ([touch view] == image4) {
[self animateFirstTouch:image4 withLocation:location];
}
}
-(void) animateFirstTouch:(UIImageView *)image withLocation:(CGPoint)location {
image.center = location;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
image.transform = CGAffineTransformMakeScale(1.5, 1.5);
[UIView commitAnimations];
}
Hope this helps you.
Contact me if you need more help.

Checking if the UIPickerView is shown or hidden? The *if* conditions?

I have a little problem with my UIPickerView animation.
I did set up the animation so when I click a button the UIPickerView will slide up and after another click it will slide down. But I hit the problem on if. I tried to set up a new settings bool and set it's value after each animation, so the if was just checking for the bool. I'm not sure if I did explained it well, but maybe you get the idea from the code.
But unfortunately it's not working... Any ideas?
- (void)viewDidLoad
{
[super viewDidLoad];
settings = [NSUserDefaults standardUserDefaults];
[settings setBool:NO forKey:#"pickerShown"];
[settings synchronize];
}
- (IBAction)showPicker:(id)sender {
CGRect rect = countryPicker.frame;
CGPoint origin = CGPointMake(0, 510); // Some off-screen y-offset here.
rect.origin = origin;
countryPicker.frame = rect;
if ([settings boolForKey:#"pickerShown"] == YES) {
// Perform transform to slide it off the screen.
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
countryPicker.transform = CGAffineTransformMakeTranslation(0, -0); // Offset.
[UIView commitAnimations];
[settings setBool:NO forKey:#"pickerShown"];
[settings synchronize];
} else if ([settings boolForKey:#"pickerShown"] == NO) {
// Perform transform to slide it onto the screen.
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
countryPicker.transform = CGAffineTransformMakeTranslation(0, -266); // Offset.
[UIView commitAnimations];
[settings setBool:YES forKey:#"pickerShown"];
[settings synchronize];
}
}
EDIT:
Just found the solution...
If anyone's interested - here it is:
The h. file:
.
.
.
{
BOOL pickerShown;
}
.
.
.
The .m file:
- (void)viewDidLoad
{
[super viewDidLoad];
CGRect rect = countryPicker.frame;
CGPoint origin = CGPointMake(0, 510); // Some off-screen y-offset here.
rect.origin = origin;
countryPicker.frame = rect;
pickerShown = NO;
}
- (IBAction)showPicker:(id)sender {
if (pickerShown == NO) {
// Perform transform to slide it onto the screen.
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1];
//[UIView setAnimationDidStopSelector:#selector(hidePicker)];
countryPicker.transform = CGAffineTransformMakeTranslation(0, 0); // Offset.
[UIView commitAnimations];
[self performSelector:#selector(hidePicker) withObject:nil afterDelay:1];
} else if (pickerShown == YES) {
//countryPicker.hidden = NO;
// Perform transform to slide it onto the screen.
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1];
countryPicker.transform = CGAffineTransformMakeTranslation(0, -266); // Offset.
[UIView commitAnimations];
countryPicker.hidden = NO;
}
}
If a view is visible on screen, it's window property will be non-nil.
Just found the solution... If anyone's interested - here it is:
The h. file:
.
.
.
{
BOOL pickerShown;
}
.
.
.
The .m file:
- (void)viewDidLoad
{
[super viewDidLoad];
CGRect rect = countryPicker.frame;
CGPoint origin = CGPointMake(0, 510); // Some off-screen y-offset here.
rect.origin = origin;
countryPicker.frame = rect;
pickerShown = NO;
}
- (IBAction)showPicker:(id)sender {
if (pickerShown == NO) {
// Perform transform to slide it onto the screen.
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1];
//[UIView setAnimationDidStopSelector:#selector(hidePicker)];
countryPicker.transform = CGAffineTransformMakeTranslation(0, 0); // Offset.
[UIView commitAnimations];
[self performSelector:#selector(hidePicker) withObject:nil afterDelay:1];
} else if (pickerShown == YES) {
//countryPicker.hidden = NO;
// Perform transform to slide it onto the screen.
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1];
countryPicker.transform = CGAffineTransformMakeTranslation(0, -266); // Offset.
[UIView commitAnimations];
countryPicker.hidden = NO;
}
}
You can check it with:
self.countryPicker.superview
If picker is hidden then superview will be nil. Otherwise it will be containing view.
If all you want is the basic effect of displaying the picker view, then removing it again there is an easier way.
pseudocode:
//do any picker initialization here
if(!pickerIsShowing)
[self.view addSubview:yourPickerView];
else
[self.yourPickerView removeFromSuperView];

Handling Device orientation problem for swapped views

i'm doing an ipad application, in which i have say two views
mainview and aboutus view
on startup i put the mainview in the rootcontroller's view (the one that is added to the window) alone.
and there's a button on mainview, that, when pressed, will remove the mainview from superview and put the aboutusview instead. aboutus has a similar button that gets us back to mainview.
Now the problem lies in the rotation (orientation).
when i detect an orientation change, i update the displayed view. works fine. (for mainview and aboutusview)
But if i rotate once any view, and then then try to see the second view. it seems that the second view is not autosizing.
CODE in rootViewController:
- (void)viewDidLoad
{
[super viewDidLoad];
_currentOrientation=UIDeviceOrientationPortrait;
[self.view addSubview:_mainView];
[_splashView removeFromSuperview];
}
-(void)viewDidAppear:(BOOL)animated
{
_currentView = _mainView;
}
-(void)toggleMainPage
{
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:.5];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:[self view] cache:YES];
[_infoView removeFromSuperview];
[self.view addSubview:_mainView];
_currentView=_mainView;
[self transformViewAccordingToOrientation:_currentOrientation];
[UIView commitAnimations];
}
-(void)toggleAboutPage
{
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:.5];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:[self view] cache:YES];
[_mainView removeFromSuperview];
[self.view addSubview:_infoView];
_currentView=_infoView;
[self transformViewAccordingToOrientation:_currentOrientation];
[UIView commitAnimations];
}
-(void) transformViewAccordingToOrientation:(UIDeviceOrientation)toInterfaceOrientation
{
if(toInterfaceOrientation == UIDeviceOrientationPortrait)
{
[_mainBtnCustom setBackgroundImage:[UIImage imageNamed:#"main.png"] forState:UIControlStateNormal];
_infoImage.image = [UIImage imageNamed:#"about.png"];
}else
{
[_mainBtnCustom setBackgroundImage:[UIImage imageNamed:#"mainr.png"] forState:UIControlStateNormal];
_infoImage.image = [UIImage imageNamed:#"aboutr.png"];
}
}
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
[self transformViewAccordingToOrientation:toInterfaceOrientation];
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
_currentOrientation = [UIDevice currentDevice].orientation;
[self transformViewAccordingToOrientation:_currentOrientation];
}
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (_currentOrientation !=interfaceOrientation);
}
what am i doing wrong?

Rotate view using CGAfffineTransformRotate

I have a circular image which I am trying to rotate, so that the yellow and black striped circle stays under the user's finger and rotates in both directions. I have this so far:
- (void)handleJogShuttle:(UIPanGestureRecognizer *)recognizer {
UIView *shuttle = [recognizer view];
if ([recognizer state] == UIGestureRecognizerStateBegan ||
[recognizer state] == UIGestureRecognizerStateChanged) {
[recognizer view].transform = CGAffineTransformRotate([[recognizer view] transform],M_PI / 20.0f);
[recognizer setTranslation:CGPointZero inView:[shuttle superview]];
}
}
Also, currently, the slightest movement can cause the view to rotate in a full circle, which is obviously not desired.
#import "RotationTestViewController.h"
#interface RotationTestViewController()
-(void)transformSpinnerwithTouches:(UITouch *)touchLocation;
-(CGPoint)vectorFromPoint:(CGPoint)firstPoint toPoint:(CGPoint)secondPoint;
-(void)animateView:(UIView *)theView toPosition:(CGAffineTransform) newTransform;
#end
#implementation RotationTestViewController
- (void)viewDidLoad {
[super viewDidLoad];}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
for (UITouch *touch in touches)
{
// Send to the dispatch method, which will make sure the appropriate subview is acted upon
// currentTouch=touch;
}
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
for (UITouch *touch in touches){
// Sends to the dispatch method, which will make sure the appropriate subview is acted upon
}
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch=[[event allTouches]anyObject];
if (touch.view==Spinner)
{
[self transformSpinnerwithTouches:touch];
}
}
-(void)transformSpinnerwithTouches:(UITouch *)touchLocation
{
CGPoint touchLocationpoint = [touchLocation locationInView:self.view];
CGPoint PrevioustouchLocationpoint = [touchLocation previousLocationInView:self.view];
//origin is the respective piont from that i gonna measure the angle of the current position with respective to previous position ....
CGPoint origin;
origin.x=Spinner.center.x;
origin.y=Spinner.center.y;
CGPoint previousDifference = [self vectorFromPoint:origin toPoint:PrevioustouchLocationpoint];
CGAffineTransform newTransform =CGAffineTransformScale(Spinner.transform, 1, 1);
CGFloat previousRotation = atan2(previousDifference.y, previousDifference.x);
CGPoint currentDifference = [self vectorFromPoint:origin toPoint:touchLocationpoint];
CGFloat currentRotation = atan2(currentDifference.y, currentDifference.x);
CGFloat newAngle = currentRotation- previousRotation;
temp1=temp1+newAngle;
NSLog(#"Angle:%F\n",(temp1*180)/M_PI);
newTransform = CGAffineTransformRotate(newTransform, newAngle);
[self animateView:Spinner toPosition:newTransform];
}
-(void)animateView:(UIView *)theView toPosition:(CGAffineTransform) newTransform
{
[UIView setAnimationsEnabled:YES];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:0.0750];
Spinner.transform = newTransform;
[UIView commitAnimations];
}
//-(CGFloat)distanceFromPoint:(CGPoint)fromPoint toPoint:(CGPoint)toPoint
//
//{
//float x = toPoint.x - fromPoint.x;
//float y = toPoint.y - fromPoint.y;
//return hypot(x, y);
//}
-(CGPoint)vectorFromPoint:(CGPoint)firstPoint toPoint:(CGPoint)secondPoint
{
CGFloat x = secondPoint.x - firstPoint.x;
CGFloat y = secondPoint.y - firstPoint.y;
CGPoint result = CGPointMake(x, y);
//NSLog(#"%f %f",x,y);
return result;
}
-(void) dealloc
{
[Spinner release];
[super dealloc];
}
I suspect this method gets called A LOT. Try using NSLog and check how many time it does.
Anyway, you are not calculating the angle properly, you could try using
-(CGPoint)translationInView:(UIView *)view
from the recognizer to calculate the correct angle to rotate.