NIHDev
NIHDev

Reputation: 1

iOS Rotation Gesture after animation

first question so take it easy!

Creating a simple iOS App. I have a view which contains a rotating dial (a UIImageView) (rotates through Rotation Gesture) and a UIButton which when pressed uses UIView animateWithDuration to move the button to one of 3 locations.

My issue.. rotating the dial is fine, moving the button is fine, BUT.. when I move the button, then rotate the dial, the location of the button is "reset" to its original frame.

How can I stop the rotation effecting the location of the button / the movement of the button.

ViewController.h

#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>

@interface ViewController : UIViewController <UIGestureRecognizerDelegate>{

IBOutlet UIImageView *lock;
IBOutlet UILabel *number;
IBOutlet UILabel *displayNumber1;
IBOutlet UILabel *displayNumber2;
IBOutlet UILabel *displayNumber3;

IBOutlet UIButton *slider;

AVAudioPlayer *theAudio;

}

@property (retain, nonatomic) IBOutlet UIImageView *lock;
@property (retain, nonatomic) IBOutlet UILabel *number;
@property (retain, nonatomic) IBOutlet UILabel *displayNumber1;
@property (retain, nonatomic) IBOutlet UILabel *displayNumber2;
@property (retain, nonatomic) IBOutlet UILabel *displayNumber3;

@property (retain, nonatomic) IBOutlet UIButton *slider;

@property (retain, nonatomic) AVAudioPlayer *theAudio;

-(IBAction)moveSlider:(id)sender;

@end

ViewController.m

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

#define RADIANS_TO_DEGREES(radians) ((radians) * (180.0 / M_PI))

@synthesize lock, number, slider, displayNumber1, displayNumber2, displayNumber3, theAudio;

CGFloat _lastRotation;
int lastNumber;
NSTimer *clickTimer;

int _whichNumberSelected;

int _currentDirection;
CGFloat _changeDirectionMatch;

float no1Left = 61;
float no2Left = 151;
float no3Left = 238;

NSString *lastText1;

CGRect newFrameSet;

- (BOOL)prefersStatusBarHidden {
    return YES;
}



- (void)viewDidLoad {
    [super viewDidLoad];

    lock.userInteractionEnabled = YES;


    UIRotationGestureRecognizer *rotationGestureRecognizer = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(handleRotationWithGestureRecognizer:)];
    rotationGestureRecognizer.delegate = self;
    [lock addGestureRecognizer:rotationGestureRecognizer];

    _lastRotation = 0;

    lastNumber = 0;


    NSString *path = [[NSBundle mainBundle] pathForResource:@"click" ofType:@"wav"];
    NSURL *fileURL = [[NSURL alloc] initFileURLWithPath: path];
    theAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:NULL];
    theAudio.volume = 1.0;
    [theAudio prepareToPlay];

    _currentDirection = 0;
    _changeDirectionMatch = 0;
    _whichNumberSelected = 1;

    lastText1 = ([NSString stringWithFormat:@"0"]);

}



-(IBAction)moveSlider:(id)sender {

    [UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
        CGRect newFrame = slider.frame;
        switch (_whichNumberSelected) {
            case 1:
                newFrame.origin.x= no2Left;
                _whichNumberSelected = 2;
                break;
            case 2:
                newFrame.origin.x= no3Left;
                _whichNumberSelected = 3;
                break;
            case 3:
                newFrame.origin.x= no2Left;
                _whichNumberSelected = 4;
                break;
            case 4:
                newFrame.origin.x= no1Left;
                _whichNumberSelected = 1;
                break;

            default:
                break;
        }
        slider.frame = newFrame;
        newFrameSet = newFrame;
    } completion:nil];
}




-(void)handleRotationWithGestureRecognizer:(UIRotationGestureRecognizer *)rotationGestureRecognizer{



    CGFloat newRot = RADIANS_TO_DEGREES(rotationGestureRecognizer.rotation) / 3.6;
    lock.transform = CGAffineTransformRotate(lock.transform, rotationGestureRecognizer.rotation);
    CGFloat c = _lastRotation - newRot;
    _lastRotation = c;

    if(c < 0){
        c = c + 100;
        _lastRotation = c;
    }
    if(c >= 100){
        c = c-100;
        _lastRotation = c;
    }



    if(c >= 99.5){
        displayNumber1.text = @"0";
    } else {
        displayNumber1.text = ([NSString stringWithFormat:@"%.f", c]);
    }

    if([displayNumber1.text isEqualToString:lastText1]){
    } else {
        [theAudio play];
    }



    lastText1 = displayNumber1.text;

    rotationGestureRecognizer.rotation = 0.0;

}






- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

Upvotes: 0

Views: 112

Answers (1)

Duncan C
Duncan C

Reputation: 131471

Welcome to Stack Overflow.

My guess is that your view controller has AutoLayout active. If that's the case, you need to change your animation code so that you animate your button by manipulating one or more constraints on it rather than changing it's frame.

The problem is that when you change the frame directly, at some point something triggers a re-layout of the form, and the constraints snap it back into place. Even if you don't explicitly add constraints, the system does.

The rotation animation should be fine since that is changing the rotation on the view's transform, not it's position, and there are no constraints I'm aware of for rotation.

What you do to animate using constraints is to attach constraints to the button in IB, then control-drag from the constraints to your view controller's header to create outlets to the constraints. (Leading and top edge constraints, say.)

Then in your animation change the constant(s) on the constraint(s) and call layoutIfNeeded.

The alternative is to turn off auto-layout for your view controller, use old style "struts and springs" layout, and then your frame animation will work as always.

Upvotes: 0

Related Questions