开发者

How can I rotate a UIButton continuously and be able to stop it?

开发者 https://www.devze.com 2023-04-03 08:11 出处:网络
I want to rotate a UIButton continuously as a means of indicating that an app is recording something. Is this a good idea. I also want to be able to stop this continuous rotation.

I want to rotate a UIButton continuously as a means of indicating that an app is recording something. Is this a good idea. I also want to be able to stop this continuous rotation.

Ho开发者_如何学运维w would I use animation to do this?


Use the UIView animation method:

animateWithDuration:delay:options:animations:completion:

and use the option UIViewAnimationOptionRepeat

For example for a UIButton * outlet named button:

- (void)viewDidLoad
{
    [super viewDidLoad];
    [UIView animateWithDuration:2.0 delay:0.0 options:UIViewAnimationOptionRepeat | UIViewAnimationOptionCurveLinear animations:^{
        CGAffineTransform transform = CGAffineTransformMakeRotation(M_PI);
        self.button.transform = transform;
    } completion:NULL];
}

Since it's going round and round, I just rotate it by pi radians rather than 2pi. you could use any angle you want.

Edit

To stop the animation, just create another animation of a short duration beginning from the current state, e.g.

- (void)stopRotating {
    [UIView animateWithDuration:0.1 delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationOptionCurveLinear animations:^{
        CGAffineTransform transform = CGAffineTransformMakeRotation(M_PI * 0.05);
        self.button.transform = transform;
    } completion:NULL];
}

This provides a very short animation which overrides the current animation. Note that the angle of the transform is multiplied by 0.05 which is the ratio of 0.1/2.0 which means that the rotational speed for this little segment is the same as the continuous rotational speed.


Try below code that will help you because I run that code successfully.

    UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    [button addTarget:self action:@selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
    [button setTitle:@"Show View" forState:UIControlStateNormal];
    button.frame = CGRectMake(80.0, 210.0, 160.0, 40.0);
    [self.view addSubview:button];

    CABasicAnimation *halfTurn;
    halfTurn = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
    halfTurn.fromValue = [NSNumber numberWithFloat:0];
    halfTurn.toValue = [NSNumber numberWithFloat:((360*M_PI)/180)];
    halfTurn.duration = 0.5;
    halfTurn.repeatCount = HUGE_VALF;
    [[button layer] addAnimation:halfTurn forKey:@"180"];


I had the same problem myself. In the end I made it like that:

#pragma mark Start/StopSpining

-(void)startSpin{
   isSpining = YES;
   [self Spin];
}

-(void)stopSpin{
   isSpining = NO;
}

-(void)spin{

[UIView animateWithDuration:1.0 delay:0 options: UIViewAnimationOptionCurveLinear animations:^{
   self.spinCircle.transform = CGAffineTransformRotate(self.spinCircle.transform, M_PI/2);
}  completion:^(BOOL finished) {
                if (isSpining)
                     [self spin];
                 }];
}


Try below extension for swift 3.

extension UIView {
    func rotate360Degrees(duration: CFTimeInterval = 3) {
        let rotateAnimation = CABasicAnimation(keyPath: "transform.rotation")
        rotateAnimation.fromValue = 0.0
        rotateAnimation.toValue = CGFloat(M_PI * 2)
        rotateAnimation.isRemovedOnCompletion = false
        rotateAnimation.duration = duration
        rotateAnimation.repeatCount=Float.infinity
        self.layer.add(rotateAnimation, forKey: nil)
    }
}

For start rotation.

MyButton.rotate360Degrees()

And for Stop.

MyButton.layer.removeAllAnimations()


I suggest you don't rotate the UIButton, just the image you put on the button. Who knows what complications or overhead rotating a rectangular object that can detect touches introduces - what happened if your user somehow taps in the corner of the button and then releases the tap as the button has rotated so that the touch is now outside? Does that register a touch up inside or not?

Anyway, if you want continuous rotation use a block method:

+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion

seems to fit the bill. The complete rotation (2pi) will occur every duration and you cause it to repeat until you stop it using UIViewAnimationOptionRepeat. You can check with completion to see if you should begin another cycle when one animation cycle has ended and you can stop the animation at any time with

[myView.layer removeAllAnimations];

(If you simply want to run it until you stop it then there are other variants of this method without a completion block)


[UIView beginAnimations:nil context:nil];

[UIView setAnimationDelegate:self];

[UIView setAnimationDuration:0.3];

uiButtonObject.transform = CGAffineTransformMakeRotation(M_PI);

[UIView commitAnimations];

M_PI is the radian value of the angle you want to rotate. Run this in a loop and in a different thread. You might also want to run the above using performSelectorInMainThread method as UI changes are not permitted in the UIThread.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号