UIView 무한 360도 회전 애니메이션?
나는 회전을 시도하고 있습니다.UIImageView
360도입니다. 그리고 온라인 튜토리얼을 여러 번 살펴보았습니다.저는 그들 중 누구도 일을 못하게 할 수 없습니다.UIView
정지하거나 새 위치로 점프합니다.
- 어떻게 하면 이를 달성할 수 있을까요?
최근에 시도한 것은 다음과 같습니다.
[UIView animateWithDuration:1.0
delay:0.0
options:0
animations:^{
imageToMove.transform = CGAffineTransformMakeRotation(M_PI);
}
completion:^(BOOL finished){
NSLog(@"Done!");
}];
하지만 2*pi를 사용하면 (같은 위치라서) 전혀 움직이지 않습니다.파이(180도)만 하려고 하면 효과가 있는데 메소드를 다시 부르면 뒤로 회전합니다.
편집:
[UIView animateWithDuration:1.0
delay:0.0
options:0
animations:^{
[UIView setAnimationRepeatCount:HUGE_VALF];
[UIView setAnimationBeginsFromCurrentState:YES];
imageToMove.transform = CGAffineTransformMakeRotation(M_PI);
}
completion:^(BOOL finished){
NSLog(@"Done!");
}];
작동하지도 않습니다.은 .180
초 도, 잠일중다가다로 합니다.0
다시 시작하기 전에 도를 표시합니다.
나에게 완벽하게 맞는 방법을 찾았습니다(조금 수정했습니다): iphone UIImageView 회전
#import <QuartzCore/QuartzCore.h>
- (void) runSpinAnimationOnView:(UIView*)view duration:(CGFloat)duration rotations:(CGFloat)rotations repeat:(float)repeat {
CABasicAnimation* rotationAnimation;
rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
rotationAnimation.toValue = [NSNumber numberWithFloat: M_PI * 2.0 /* full rotation*/ * rotations * duration ];
rotationAnimation.duration = duration;
rotationAnimation.cumulative = YES;
rotationAnimation.repeatCount = repeat ? HUGE_VALF : 0;
[view.layer addAnimation:rotationAnimation forKey:@"rotationAnimation"];
}
Richard J. Ross 3세에게 그 아이디어를 칭찬했지만, 저는 그의 코드가 제가 필요로 하는 것이 아니라는 것을 발견했습니다.은 " " 입니다.options
나는 당신에게 주는 것이라고 믿습니다.UIViewAnimationOptionCurveEaseInOut
지속적인 애니메이션에서는 제대로 보이지 않습니다.또한 필요한 경우 짝수 분기 회전에서 애니메이션을 중지할 수 있도록 체크 표시를 추가했으며(무한하지는 않지만 지속 시간이 무한함), 처음 90도 동안 가속 램프를 올리고 마지막 90도 동안 감속했습니다(정지 요청 후).
// an ivar for your class:
BOOL animating;
- (void)spinWithOptions:(UIViewAnimationOptions)options {
// this spin completes 360 degrees every 2 seconds
[UIView animateWithDuration:0.5
delay:0
options:options
animations:^{
self.imageToMove.transform = CGAffineTransformRotate(imageToMove.transform, M_PI / 2);
}
completion:^(BOOL finished) {
if (finished) {
if (animating) {
// if flag still set, keep spinning with constant speed
[self spinWithOptions: UIViewAnimationOptionCurveLinear];
} else if (options != UIViewAnimationOptionCurveEaseOut) {
// one last spin, with deceleration
[self spinWithOptions: UIViewAnimationOptionCurveEaseOut];
}
}
}];
}
- (void)startSpin {
if (!animating) {
animating = YES;
[self spinWithOptions: UIViewAnimationOptionCurveEaseIn];
}
}
- (void)stopSpin {
// set the flag to stop spinning after one last 90 degree increment
animating = NO;
}
갱신하다
회전을 다시 시작하기 위한 요청을 처리할 수 있는 기능을 추가했습니다(startSpin
), 이전 스핀이 감겨지는 동안(흔들림).여기 Github에 있는 샘플 프로젝트.
Swift에서 무한 회전을 위해 다음 코드를 사용할 수 있습니다.
스위프트 4
extension UIView {
private static let kRotationAnimationKey = "rotationanimationkey"
func rotate(duration: Double = 1) {
if layer.animation(forKey: UIView.kRotationAnimationKey) == nil {
let rotationAnimation = CABasicAnimation(keyPath: "transform.rotation")
rotationAnimation.fromValue = 0.0
rotationAnimation.toValue = Float.pi * 2.0
rotationAnimation.duration = duration
rotationAnimation.repeatCount = Float.infinity
layer.add(rotationAnimation, forKey: UIView.kRotationAnimationKey)
}
}
func stopRotating() {
if layer.animation(forKey: UIView.kRotationAnimationKey) != nil {
layer.removeAnimation(forKey: UIView.kRotationAnimationKey)
}
}
}
스위프트 3
let kRotationAnimationKey = "com.myapplication.rotationanimationkey" // Any key
func rotateView(view: UIView, duration: Double = 1) {
if view.layer.animationForKey(kRotationAnimationKey) == nil {
let rotationAnimation = CABasicAnimation(keyPath: "transform.rotation")
rotationAnimation.fromValue = 0.0
rotationAnimation.toValue = Float(M_PI * 2.0)
rotationAnimation.duration = duration
rotationAnimation.repeatCount = Float.infinity
view.layer.addAnimation(rotationAnimation, forKey: kRotationAnimationKey)
}
}
중지는 다음과 같습니다.
func stopRotatingView(view: UIView) {
if view.layer.animationForKey(kRotationAnimationKey) != nil {
view.layer.removeAnimationForKey(kRotationAnimationKey)
}
}
위의 네이트의 답변은 애니메이션 중지 및 시작에 이상적이며 더 나은 제어를 제공합니다.나는 왜 당신의 것과 그의 것이 작동하지 않는지 궁금했습니다.저는 여기서 제 연구 결과와 UIView를 지연 없이 지속적으로 애니메이션화할 수 있는 더 간단한 버전의 코드를 공유하고 싶었습니다.
이게 제가 사용한 코드입니다.
- (void)rotateImageView
{
[UIView animateWithDuration:1 delay:0 options:UIViewAnimationOptionCurveLinear animations:^{
[self.imageView setTransform:CGAffineTransformRotate(self.imageView.transform, M_PI_2)];
}completion:^(BOOL finished){
if (finished) {
[self rotateImageView];
}
}];
}
나는 'CGAfineTransformMakeRotation' 대신 'CGAfineTransformRotate'를 사용했는데, 왜냐하면 전자는 애니메이션 진행 시 저장된 결과를 반환하기 때문입니다.이렇게 하면 애니메이션 중에 보기가 점프하거나 재설정되지 않습니다.
또 다른 것은 '를 사용하지 않는 것입니다.'UIViewAnimationOptionRepeat'은 애니메이션이 반복되기 전에 변환을 재설정하여 보기를 원래 위치로 이동시키기 때문에 반복합니다.반복 대신 애니메이션 블록이 사실상 종료되지 않으므로 변환이 원래 값으로 재설정되지 않도록 반복합니다.
마지막으로 360도 또는 180도(2*M_PI 또는 M_PI)가 아닌 90도(M_PI/2)의 단계로 뷰를 변환해야 합니다.변환은 사인 값과 코사인 값의 행렬 곱셈으로 발생하기 때문입니다.
t' = [ cos(angle) sin(angle) -sin(angle) cos(angle) 0 0 ] * t
따라서 180도 변환을 사용하는 경우 180의 코사인이 -1을 산출하여 매번 반대 방향으로 뷰가 변환됩니다(변환의 라디안 값을 M_PI로 변경하면 Note-Nate의 답변에도 이 문제가 발생합니다).360도 변환은 단순히 뷰를 원래 위치에 유지하도록 요청하는 것입니다. 따라서 회전을 전혀 볼 수 없습니다.
확인된 솔루션의 Swift Extension에 대한 나의 기여:
스위프트 4.0
extension UIView{
func rotate() {
let rotation : CABasicAnimation = CABasicAnimation(keyPath: "transform.rotation.z")
rotation.toValue = NSNumber(value: Double.pi * 2)
rotation.duration = 1
rotation.isCumulative = true
rotation.repeatCount = Float.greatestFiniteMagnitude
self.layer.add(rotation, forKey: "rotationAnimation")
}
}
사용되지 않음:
extension UIView{
func rotate() {
let rotation : CABasicAnimation = CABasicAnimation(keyPath: "transform.rotation.z")
rotation.toValue = NSNumber(double: M_PI * 2)
rotation.duration = 1
rotation.cumulative = true
rotation.repeatCount = FLT_MAX
self.layer.addAnimation(rotation, forKey: "rotationAnimation")
}
}
이미지를 무한대로 회전하기만 하면 매우 효과적이며 매우 간단합니다.
NSTimeInterval duration = 10.0f;
CGFloat angle = M_PI / 2.0f;
CGAffineTransform rotateTransform = CGAffineTransformRotate(imageView.transform, angle);
[UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionRepeat| UIViewAnimationOptionCurveLinear animations:^{
imageView.transform = rotateTransform;
} completion:nil];
제 경험에 따르면, 이것은 완벽하게 작동하지만, 이미지가 오프셋 없이 중심을 중심으로 회전할 수 있는지 확인하십시오. 그렇지 않으면 이미지 애니메이션이 PI로 이동하면 "점프"할 것입니다.
스핀 방향을 변경하려면 다음 기호를 변경합니다.angle
(angle *= -1
).
@AlexPretzlav의 "Update Comments by @AlexPretzlav"는 제가 이 글을 쓸 때 제가 회전하고 있는 이미지가 세로축과 가로축을 따라 대칭을 이루고 있다는 것을 깨달았습니다. 즉, 이미지가 90도만 회전하고 다시 설정됩니다. 비록 계속해서 회전하는 것처럼 보였지만 말입니다.
그래서, 만약 당신의 이미지가 제 것과 같다면, 이것은 잘 작동할 것입니다. 하지만 이미지가 대칭적이지 않다면, 당신은 90도 후에 원래 방향으로 "똑딱" 돌아가는 것을 알아차릴 것입니다.
비대칭 이미지를 회전하려면 승인된 답변을 사용하는 것이 좋습니다.
아래와 같은 덜 우아한 솔루션 중 하나는 이미지를 회전시키지만 애니메이션을 다시 시작할 때 눈에 띄는 흔들림이 있을 수 있습니다.
- (void)spin
{
NSTimeInterval duration = 0.5f;
CGFloat angle = M_PI_2;
CGAffineTransform rotateTransform = CGAffineTransformRotate(self.imageView.transform, angle);
[UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionCurveLinear animations:^{
self.imageView.transform = rotateTransform;
} completion:^(BOOL finished) {
[self spin];
}];
}
@richard-j-ross-ii가 제안하는 것처럼 블록만으로 이 작업을 수행할 수도 있지만 블록이 자체적으로 캡처되고 있기 때문에 유지 루프 경고가 표시됩니다.
__block void(^spin)() = ^{
NSTimeInterval duration = 0.5f;
CGFloat angle = M_PI_2;
CGAffineTransform rotateTransform = CGAffineTransformRotate(self.imageView.transform, angle);
[UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionCurveLinear animations:^{
self.imageView.transform = rotateTransform;
} completion:^(BOOL finished) {
spin();
}];
};
spin();
David Rysanek의 멋진 답변이 Swift 4로 업데이트되었습니다.
import UIKit
extension UIView {
func startRotating(duration: CFTimeInterval = 3, repeatCount: Float = Float.infinity, clockwise: Bool = true) {
if self.layer.animation(forKey: "transform.rotation.z") != nil {
return
}
let animation = CABasicAnimation(keyPath: "transform.rotation.z")
let direction = clockwise ? 1.0 : -1.0
animation.toValue = NSNumber(value: .pi * 2 * direction)
animation.duration = duration
animation.isCumulative = true
animation.repeatCount = repeatCount
self.layer.add(animation, forKey:"transform.rotation.z")
}
func stopRotating() {
self.layer.removeAnimation(forKey: "transform.rotation.z")
}
}
}
UIView 확장자로서 신속한 해결책이 있습니다.UIA 활동의 시뮬레이션으로 간주할 수 있습니다.UI 이미지 보기의 표시기 동작입니다.
import UIKit
extension UIView
{
/**
Starts rotating the view around Z axis.
@param duration Duration of one full 360 degrees rotation. One second is default.
@param repeatCount How many times the spin should be done. If not provided, the view will spin forever.
@param clockwise Direction of the rotation. Default is clockwise (true).
*/
func startZRotation(duration duration: CFTimeInterval = 1, repeatCount: Float = Float.infinity, clockwise: Bool = true)
{
if self.layer.animationForKey("transform.rotation.z") != nil {
return
}
let animation = CABasicAnimation(keyPath: "transform.rotation.z")
let direction = clockwise ? 1.0 : -1.0
animation.toValue = NSNumber(double: M_PI * 2 * direction)
animation.duration = duration
animation.cumulative = true
animation.repeatCount = repeatCount
self.layer.addAnimation(animation, forKey:"transform.rotation.z")
}
/// Stop rotating the view around Z axis.
func stopZRotation()
{
self.layer.removeAnimationForKey("transform.rotation.z")
}
}
이것은 저에게 효과가 있었습니다.
[UIView animateWithDuration:1.0
animations:^
{
self.imageView.transform = CGAffineTransformMakeRotation(M_PI);
self.imageView.transform = CGAffineTransformMakeRotation(0);
}];
쿼터 턴을 사용하고 턴을 점진적으로 증가시킵니다.
void (^block)() = ^{
imageToMove.transform = CGAffineTransformRotate(imageToMove.transform, M_PI / 2);
}
void (^completion)(BOOL) = ^(BOOL finished){
[UIView animateWithDuration:1.0
delay:0.0
options:0
animations:block
completion:completion];
}
completion(YES);
이 저장소에서 좋은 코드를 찾았습니다.
여기 제가 속도에 대한 필요에 따라 작은 변경을 한 코드가 있습니다 :)
UIImageView+Rotate.
#import <Foundation/Foundation.h>
@interface UIImageView (Rotate)
- (void)rotate360WithDuration:(CGFloat)duration repeatCount:(float)repeatCount;
- (void)pauseAnimations;
- (void)resumeAnimations;
- (void)stopAllAnimations;
@end
UIImageView+Rotate.m
#import <QuartzCore/QuartzCore.h>
#import "UIImageView+Rotate.h"
@implementation UIImageView (Rotate)
- (void)rotate360WithDuration:(CGFloat)duration repeatCount:(float)repeatCount
{
CABasicAnimation *fullRotation;
fullRotation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
fullRotation.fromValue = [NSNumber numberWithFloat:0];
//fullRotation.toValue = [NSNumber numberWithFloat:(2*M_PI)];
fullRotation.toValue = [NSNumber numberWithFloat:-(2*M_PI)]; // added this minus sign as i want to rotate it to anticlockwise
fullRotation.duration = duration;
fullRotation.speed = 2.0f; // Changed rotation speed
if (repeatCount == 0)
fullRotation.repeatCount = MAXFLOAT;
else
fullRotation.repeatCount = repeatCount;
[self.layer addAnimation:fullRotation forKey:@"360"];
}
//Not using this methods :)
- (void)stopAllAnimations
{
[self.layer removeAllAnimations];
};
- (void)pauseAnimations
{
[self pauseLayer:self.layer];
}
- (void)resumeAnimations
{
[self resumeLayer:self.layer];
}
- (void)pauseLayer:(CALayer *)layer
{
CFTimeInterval pausedTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil];
layer.speed = 0.0;
layer.timeOffset = pausedTime;
}
- (void)resumeLayer:(CALayer *)layer
{
CFTimeInterval pausedTime = [layer timeOffset];
layer.speed = 1.0;
layer.timeOffset = 0.0;
layer.beginTime = 0.0;
CFTimeInterval timeSincePause = [layer convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime;
layer.beginTime = timeSincePause;
}
@end
Swift3 버전:
extension UIView {
func startRotate() {
let rotation : CABasicAnimation = CABasicAnimation(keyPath: "transform.rotation.z")
rotation.fromValue = 0
rotation.toValue = NSNumber(value: M_PI * 2)
rotation.duration = 2
rotation.isCumulative = true
rotation.repeatCount = FLT_MAX
self.layer.add(rotation, forKey: "rotationAnimation")
}
func stopRotate() {
self.layer.removeAnimation(forKey: "rotationAnimation")
}
}
그리고 전화하는 것을 기억하세요.startRotate
에viewWillAppear
에 없는viewDidLoad
.
@ram의 대답은 정말 도움이 되었습니다.여기 스위프트 버전의 답이 있습니다.
스위프트 2
private func rotateImageView() {
UIView.animateWithDuration(1, delay: 0, options: UIViewAnimationOptions.CurveLinear, animations: { () -> Void in
self.imageView.transform = CGAffineTransformRotate(self.imageView.transform, CGFloat(M_PI_2))
}) { (finished) -> Void in
if finished {
self.rotateImageView()
}
}
}
스위프트 3,4,5
private func rotateImageView() {
UIView.animate(withDuration: 1, delay: 0, options: UIView.AnimationOptions.curveLinear, animations: { () -> Void in
self.imageView.transform = self.imageView.transform.rotated(by: .pi / 2)
}) { (finished) -> Void in
if finished {
self.rotateImageView()
}
}
}
또한 UIView 및 블록을 사용하여 동일한 유형의 애니메이션을 수행할 수 있습니다.보기를 임의의 각도로 회전할 수 있는 클래스 확장 방법이 있습니다.
- (void)rotationWithDuration:(NSTimeInterval)duration angle:(CGFloat)angle options:(UIViewAnimationOptions)options
{
// Repeat a quarter rotation as many times as needed to complete the full rotation
CGFloat sign = angle > 0 ? 1 : -1;
__block NSUInteger numberRepeats = floorf(fabsf(angle) / M_PI_2);
CGFloat quarterDuration = duration * M_PI_2 / fabs(angle);
CGFloat lastRotation = angle - sign * numberRepeats * M_PI_2;
CGFloat lastDuration = duration - quarterDuration * numberRepeats;
__block UIViewAnimationOptions startOptions = UIViewAnimationOptionBeginFromCurrentState;
UIViewAnimationOptions endOptions = UIViewAnimationOptionBeginFromCurrentState;
if (options & UIViewAnimationOptionCurveEaseIn || options == UIViewAnimationOptionCurveEaseInOut) {
startOptions |= UIViewAnimationOptionCurveEaseIn;
} else {
startOptions |= UIViewAnimationOptionCurveLinear;
}
if (options & UIViewAnimationOptionCurveEaseOut || options == UIViewAnimationOptionCurveEaseInOut) {
endOptions |= UIViewAnimationOptionCurveEaseOut;
} else {
endOptions |= UIViewAnimationOptionCurveLinear;
}
void (^lastRotationBlock)(void) = ^ {
[UIView animateWithDuration:lastDuration
delay:0
options:endOptions
animations:^{
self.transform = CGAffineTransformRotate(self.transform, lastRotation);
}
completion:^(BOOL finished) {
NSLog(@"Animation completed");
}
];
};
if (numberRepeats) {
__block void (^quarterSpinningBlock)(void) = ^{
[UIView animateWithDuration:quarterDuration
delay:0
options:startOptions
animations:^{
self.transform = CGAffineTransformRotate(self.transform, M_PI_2);
numberRepeats--;
}
completion:^(BOOL finished) {
if (numberRepeats > 0) {
startOptions = UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationOptionCurveLinear;
quarterSpinningBlock();
} else {
lastRotationBlock();
}NSLog(@"Animation completed");
}
];
};
quarterSpinningBlock();
} else {
lastRotationBlock();
}
}
네이츠의 해결책을 원했지만 신속한 해결책을 원하는 사람이 있다면 대략적인 신속한 번역은 다음과 같습니다.
class SomeClass: UIViewController {
var animating : Bool = false
@IBOutlet weak var activityIndicatorImage: UIImageView!
func startSpinning() {
if(!animating) {
animating = true;
spinWithOptions(UIViewAnimationOptions.CurveEaseIn);
}
}
func stopSpinning() {
animating = false
}
func spinWithOptions(options: UIViewAnimationOptions) {
UIView.animateWithDuration(0.5, delay: 0.0, options: options, animations: { () -> Void in
let val : CGFloat = CGFloat((M_PI / Double(2.0)));
self.activityIndicatorImage.transform = CGAffineTransformRotate(self.activityIndicatorImage.transform,val)
}) { (finished: Bool) -> Void in
if(finished) {
if(self.animating){
self.spinWithOptions(UIViewAnimationOptions.CurveLinear)
} else if (options != UIViewAnimationOptions.CurveEaseOut) {
self.spinWithOptions(UIViewAnimationOptions.CurveEaseOut)
}
}
}
}
override func viewDidLoad() {
startSpinning()
}
}
사마리니오스의 경우:
public static void RotateAnimation (this UIView view, float duration=1, float rotations=1, float repeat=int.MaxValue)
{
var rotationAnimation = CABasicAnimation.FromKeyPath ("transform.rotation.z");
rotationAnimation.To = new NSNumber (Math.PI * 2.0 /* full rotation*/ * 1 * 1);
rotationAnimation.Duration = 1;
rotationAnimation.Cumulative = true;
rotationAnimation.RepeatCount = int.MaxValue;
rotationAnimation.RemovedOnCompletion = false;
view.Layer.AddAnimation (rotationAnimation, "rotationAnimation");
}
이렇게 360도 오른쪽 방향으로 회전합니다.
[UIView animateWithDuration:1.0f delay:0.0f options:UIViewAnimationOptionRepeat|UIViewAnimationOptionCurveLinear
animations:^{
[imageIndView setTransform:CGAffineTransformRotate([imageIndView transform], M_PI-0.00001f)];
} completion:nil];
애니메이션 만들기
- (CABasicAnimation *)spinAnimationWithDuration:(CGFloat)duration clockwise:(BOOL)clockwise repeat:(BOOL)repeats
{
CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
anim.toValue = clockwise ? @(M_PI * 2.0) : @(M_PI * -2.0);
anim.duration = duration;
anim.cumulative = YES;
anim.repeatCount = repeats ? CGFLOAT_MAX : 0;
return anim;
}
다음과 같은 보기에 추가
CABasicAnimation *animation = [self spinAnimationWithDuration:1.0 clockwise:YES repeat:YES];
[self.spinningView.layer addAnimation:animation forKey:@"rotationAnimation"];
이 대답은 어떻게 다릅니까?만약 당신의 대부분의 기능이 단지 몇몇 객체를 여기저기서 조작하는 것이 아니라 객체를 반환한다면 당신은 훨씬 더 깨끗한 코드를 갖게 될 것입니다.
UIView를 사용하여 360도 애니메이션을 수행하는 방법은 다음과 같습니다.
CABasic 애니메이션 사용
var rotationAnimation = CABasicAnimation()
rotationAnimation = CABasicAnimation.init(keyPath: "transform.rotation.z")
rotationAnimation.toValue = NSNumber(value: (Double.pi))
rotationAnimation.duration = 1.0
rotationAnimation.isCumulative = true
rotationAnimation.repeatCount = 100.0
view.layer.add(rotationAnimation, forKey: "rotationAnimation")
다음은 회전 시작 및 중지 작업을 처리하는 UIView의 확장 기능입니다.
extension UIView {
// Start rotation
func startRotation() {
let rotation = CABasicAnimation(keyPath: "transform.rotation.z")
rotation.fromValue = 0
rotation.toValue = NSNumber(value: Double.pi)
rotation.duration = 1.0
rotation.isCumulative = true
rotation.repeatCount = FLT_MAX
self.layer.add(rotation, forKey: "rotationAnimation")
}
// Stop rotation
func stopRotation() {
self.layer.removeAnimation(forKey: "rotationAnimation")
}
}
이제 UIView.애니메이션 클로저를 사용합니다.
UIView.animate(withDuration: 0.5, animations: {
view.transform = CGAffineTransform(rotationAngle: (CGFloat(Double.pi))
}) { (isAnimationComplete) in
// Animation completed
}
키프레임 애니메이션을 이용한 Swift 5 UIView 확장
이 접근 방식을 통해 UIView를 직접 사용할 수 있습니다.애니메이션 옵션.반복
public extension UIView {
func animateRotation(duration: TimeInterval, repeat: Bool, completion: ((Bool) -> ())?) {
var options = UIView.KeyframeAnimationOptions(rawValue: UIView.AnimationOptions.curveLinear.rawValue)
if `repeat` {
options.insert(.repeat)
}
UIView.animateKeyframes(withDuration: duration, delay: 0, options: options, animations: {
UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 0.25, animations: {
self.transform = CGAffineTransform(rotationAngle: CGFloat.pi/2)
})
UIView.addKeyframe(withRelativeStartTime: 0.25, relativeDuration: 0.25, animations: {
self.transform = CGAffineTransform(rotationAngle: CGFloat.pi)
})
UIView.addKeyframe(withRelativeStartTime: 0.5, relativeDuration: 0.25, animations: {
self.transform = CGAffineTransform(rotationAngle: 3*CGFloat.pi/2)
})
UIView.addKeyframe(withRelativeStartTime: 0.75, relativeDuration: 0.25, animations: {
self.transform = CGAffineTransform(rotationAngle: 2*CGFloat.pi)
})
}, completion: completion)
}
}
시간을 절약할 수 있는 빛나는 애니메이션 프레임워크를 개발했습니다!이를 사용하여 이 애니메이션을 매우 쉽게 만들 수 있습니다.
private var endlessRotater: EndlessAnimator!
override func viewDidAppear(animated: Bool)
{
super.viewDidAppear(animated)
let rotationAnimation = AdditiveRotateAnimator(M_PI).to(targetView).duration(2.0).baseAnimation(.CurveLinear)
endlessRotater = EndlessAnimator(rotationAnimation)
endlessRotater.animate()
}
이 애니메이션을 중지하려면 간단히 설정합니다.nil
로.endlessRotater
.
관심이 있으시다면, https://github.com/hip4yes/Animatics 을 보세요.
스위프트 4,
func rotateImage(image: UIImageView) {
UIView.animate(withDuration: 1, animations: {
image.transform = CGAffineTransform(rotationAngle: CGFloat.pi)
image.transform = CGAffineTransform.identity
}) { (completed) in
self.rotateImage()
}
}
스위프트 4.0
func rotateImageView()
{
UIView.animate(withDuration: 0.3, delay: 0, options: .curveLinear, animations: {() -> Void in
self.imageView.transform = self.imageView.transform.rotated(by: .pi / 2)
}, completion: {(_ finished: Bool) -> Void in
if finished {
rotateImageView()
}
})
}
스위프트:
func runSpinAnimationOnView(view:UIView , duration:Float, rotations:Double, repeatt:Float ) ->()
{
let rotationAnimation=CABasicAnimation();
rotationAnimation.keyPath="transform.rotation.z"
let toValue = M_PI * 2.0 * rotations ;
// passing it a float
let someInterval = CFTimeInterval(duration)
rotationAnimation.toValue=toValue;
rotationAnimation.duration=someInterval;
rotationAnimation.cumulative=true;
rotationAnimation.repeatCount=repeatt;
view.layer.addAnimation(rotationAnimation, forKey: "rotationAnimation")
}
스위프트 3:
var rotationAnimation = CABasicAnimation()
rotationAnimation = CABasicAnimation.init(keyPath: "transform.rotation.z")
rotationAnimation.toValue = NSNumber(value: (M_PI * 2.0))
rotationAnimation.duration = 2.0
rotationAnimation.isCumulative = true
rotationAnimation.repeatCount = 10.0
view.layer.add(rotationAnimation, forKey: "rotationAnimation")
let val = CGFloat(M_PI_2)
UIView.animate(withDuration: 1, delay: 0, options: [.repeat, .curveLinear], animations: {
self.viewToRotate.transform = self.viewToRotate.transform.rotated(by: val)
})
import UIKit
class RotatingImageView: UIImageView, CAAnimationDelegate {
private let rotationAnimationKey = "rotationAnimationKey"
private var shouldStopRotating = false
func startRotating(witFullRotationDuration duration: Double = 0.5, halfRotation: Bool = true) {
shouldStopRotating = false
if layer.animation(forKey: rotationAnimationKey) == nil {
let rotationAnimation = CABasicAnimation(keyPath: "transform.rotation")
rotationAnimation.fromValue = 0.0
rotationAnimation.toValue = halfRotation ? Float.pi : Float.pi * 2
rotationAnimation.duration = duration
rotationAnimation.repeatCount = 1
rotationAnimation.delegate = self
layer.add(rotationAnimation, forKey: rotationAnimationKey)
}
}
func stopRotating(immediately: Bool = false) {
if immediately {
if layer.animation(forKey: rotationAnimationKey) != nil {
layer.removeAnimation(forKey: rotationAnimationKey)
}
} else {
shouldStopRotating = true
}
}
func animationDidStop(_ anim: CAAnimation, finished flag: Bool) {
if !shouldStopRotating {
startRotating(witFullRotationDuration: anim.duration)
} else {
if layer.animation(forKey: rotationAnimationKey) != nil {
layer.removeAnimation(forKey: rotationAnimationKey)
}
}
}
}
제 생각에 당신은 추가하는 것이 좋을 것 같습니다.UIVIew
범주:
#import <QuartzCore/QuartzCore.h>
#import "UIView+Rotate.h"
구현 UI뷰(회전)
(void)remrotate360WithDuration:(CGFloat)duration repeatCount: (float)repeatCount { CABasicAnimation *fullRotation; fullRotation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"]; fullRotation.fromValue = [NSNumber numberWithFloat:0]; fullRotation.toValue = [NSNumber numberWithFloat:(2*M_PI)]; // fullRotation.toValue = [NSNumber numberWithFloat:-(2*M_PI)]; // added this minus sign as i want to rotate it to anticlockwise fullRotation.duration = duration; fullRotation.speed = 2.0f; // Changed rotation speed if (repeatCount == 0) fullRotation.repeatCount = MAXFLOAT; else fullRotation.repeatCount = repeatCount; [self.layer addAnimation:fullRotation forKey:@"360"]; }
이 방법을 사용하지 않음 :)
(void)remstopAllAnimations { [self.layer removeAllAnimations]; };
(void)rempauseAnimations { [self rempauseLayer:self.layer]; }
(void)remresumeAnimations { [self remresumeLayer:self.layer]; }
(void)rempauseLayer:(CALayer *)layer { CFTimeInterval pausedTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil]; layer.speed = 0.0; layer.timeOffset = pausedTime; }
(void)remresumeLayer:(CALayer *)layer { CFTimeInterval pausedTime = [layer timeOffset]; layer.speed = 1.0; layer.timeOffset = 0.0; layer.beginTime = 0.0; CFTimeInterval timeSincePause = [layer convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime; layer.beginTime = timeSincePause; }
언급URL : https://stackoverflow.com/questions/9844925/uiview-infinite-360-degree-rotation-animation
'it-source' 카테고리의 다른 글
bash의 코드 줄 수(공백이 아닌) (0) | 2023.04.26 |
---|---|
WPF 명령 대 이벤트 장점/단점 (0) | 2023.04.26 |
코드백에 정의된 바인딩 개체 (0) | 2023.04.26 |
엔티티 프레임워크를 "준비"하는 방법은 무엇입니까?언제 추워집니까? (0) | 2023.04.26 |
Angular에서 로컬 스토리지를 사용하는 방법 (0) | 2023.04.26 |