如何让UIView一直移动?

时间:2014-02-24 19:44:12

标签: ios iphone objective-c

只要应用程序正在运行,我就会尝试为对象设置动画。 这似乎不起作用:

for (int i = -100; i < 200; i++) {
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.5];
    [_targetView setFrame:CGRectMake(i, _targetView.frame.origin.y, _targetView.frame.size.width, _targetView.frame.size.height)];
    [UIView commitAnimations];

    if (i == 200) {
        [self anotherLoopThatGoesBackFrom200to-100];
    }
}

_targetView是一个位于屏幕底部的UIView。

感谢。

5 个答案:

答案 0 :(得分:2)

有一个动画可以将视图从屏幕的一侧移动到另一侧。将其设置为自动重复和自动反转:

// Assume your view starts with a center of 50,50
[UIView animateWithDuration:1.0 delay:0 options:UIViewAnimationOptionRepeat | UIViewAnimationOptionAutoreverse animations:^{
    view.center = CGPointMake(270,50);
} completion:nil];

这是使用基于块的语法,建议使用基于块的语法。

您需要调整中心和时间值以适合您的目的。您还可以添加时序曲线以使动画更有趣,只需在曲线选项中|(有关示例,请参阅documentation)。

答案 1 :(得分:1)

为什么这不起作用?

for (int i = -100; i < 200; i++) {

[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
[_targetView setFrame:CGRectMake(i, _targetView.frame.origin.y , _targetView.frame.size.width, _targetView.frame.size.height)];
[UIView commitAnimations];

if (i == 200) {
    [self anotherLoopThatGoesBackFrom200to-100];
}

}

当您在当前运行循环中提交动画时,它们不会立即执行。你已经连续创建了300个动画,然后要求运行时执行它们 - 它也会执行你提出的最后一个动画,因为它在你覆盖它之前没有时间去做之前的动画。您想要建立一系列动画。有一个方法将采用completionBlock,这是在当前动画完成后将发生的一大块代码:你应该使用它。

你也是以错误的方式接近这个抱歉:不要为动画的每个阶段设置框架 - 这就是UIKit将为你处理的内容!它将适应帧率变化,创建KVO通知并使其更简单。

在动画块之前设置开始帧,将最终位置放在动画块内。动画将自然发生

答案 2 :(得分:0)

有几种方法可以做到这一点,这里有两种。首先,您可以使用animateWithDuration: completion:这样的UIView类方法

 -(void) animateBlueRect {

     _block WhateverClassThisIs selfReference = self; 
     void (^animationBlock) () = ^void {

           _targetView.frame = //whatever 
     };
     [UIView animateWithDuration: someDuration animations: animationBlock completion: ^(BOOL finished) {

         [selfReference animateBlueRect]
    }];
}

或者你可以使用CADDisplayLink,并跟踪你的矩形在其回调中使用的属性中的移动距离,如下所示:

 //inside your .h file, or a class extension in your .m
 @property (assign) float currFramePos;

 //inside your setup method
 CADisplayLink link =  [CADisplayLink displayLinkWithTarget: self selector: blueRectMover];
 [link addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]

 //a seperate method
 -(void) blueRectMover
 {
     currFramePos++;
     if (currFramePos > 200) {
       _targetView.frame = CGRectMake(currFramePos, 0, 100, 100)
     }

      else {_targetView.frame = CGRectMake(-100, 0, 100, 100); 

      }
 }

答案 3 :(得分:0)

或者:

[UIView animateWithDuration:10.
                      delay:0.
                    options:UIViewAnimationCurveLinear|UIViewAnimationOptionAutoreverse|UIViewAnimationOptionRepeat
                 animations:^{
    _bouncingView.frame = frame;
} completion:nil];

[UIView beginAnimations:@"bounce" context:nil];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
[UIView setAnimationDuration:10.];
[UIView setAnimationDelay:0.];
[UIView setAnimationRepeatAutoreverses:YES];
[UIView setAnimationRepeatCount:INFINITY];
_bouncingView.frame = frame;
[UIView commitAnimations];

答案 4 :(得分:0)

精灵套件

如果你正在研究制作游戏,我建议你研究一下iOS 7附带的Sprite Kit(还有一个模板项目)。

使用SpriteKit,您可以一起添加和链接操作来描述行为:

SKAction *right = [SKAction moveToX:self.size.width duration:2.0];
SKAction *left  = [SKAction moveToX:0.0             duration:2.0];

SKAction *moveLeftAndRight = [SKAction repeatActionForever:[SKAction sequence:@[right, left]]];

[sprite runAction:moveLeftAndRight];

CAAnimation

如果您不喜欢使用SpriteKit,并且想要做某事,请查看CoreAnimation。链接并导入QuartzCore(iOS 7上不需要链接):

#import <QuartzCore/QuartzCore.h>

然后添加动画:

CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position.x"];

animation.keyTimes      = @[@(0.0), @(0.5), @(1.0)];
animation.values        = @[@(0.0),@(320.0),@(0.0)];
animation.duration      = 0.5;
animation.repeatCount   = HUGE_VALF;

[_targetView.layer addAnimation:animation forKey:@"bounceLeftRight"];