繁体   English   中英

动画后的iOS旋转手势

[英]iOS Rotation Gesture after animation

第一个问题,请放轻松!

创建一个简单的iOS应用。 我有一个视图,其中包含一个旋转刻度盘(一个UIImageView)(通过“旋转手势”旋转)和一个UIButton,当按下按钮时,它将使用UIView animateWithDuration将按钮移至3个位置之一。

我的问题..旋转转盘很好,移动按钮也很好,但是..当我移动按钮,然后旋转转盘时,按钮的位置“重置”为其原始框架。

如何停止影响按钮位置/按钮移动的旋转。

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

欢迎使用堆栈溢出。

我的猜测是您的视图控制器具有自动布局功能。 在这种情况下,您需要更改动画代码,以便通过对按钮进行一个或多个约束而不是更改其帧来对按钮进行动画处理。

问题在于,当您直接更改框架时,有时会触发表单的重新布局,并且约束会将其重新固定到位。 即使您没有显式添加约束,系统也会这样做。

旋转动画应该没问题,因为这会改变视图变换的旋转,而不是位置,并且我没有意识到旋转的约束。

使用约束进行动画处理的方法是将约束附加到IB中的按钮,然后从约束中拖动控件到视图控制器的标题以创建约束的出口。 (例如,领先和最高边缘约束。)

然后在动画中更改约束上的常量,然后调用layoutIfNeeded。

另一种方法是关闭视图控制器的自动布局,使用旧式的“支柱和弹簧”布局,然后帧动画将照常工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM