2014-09-10 109 views
1

我试图让一个UIView动画作为浮动对象,或作为气球:D UIView在屏幕的中间,我希望它保持随机浮动它的第一个启动点。没有穿过屏幕或类似的东西,只是漂浮在它周围5个像素的区域。如何动画浮动UIView在ObjectiveC

有什么建议吗? :d

我尝试这样做:

[UIView animateWithDuration:0.1 
         delay:0.0 
        options: UIViewAnimationOptionRepeat | UIViewAnimationOptionAutoreverse | UIViewAnimationOptionAllowUserInteraction 
       animations:^{ 
        myCircleUIView.transform = CGAffineTransformMakeTranslation([self randomFloatingGenerator], [self randomFloatingGenerator]); 
       } 
       completion:NULL]; 

randomFloatingGenerator生成-5之间的数字和5问题是,它仅执行一次,并保持着相同的随机值的重复。

EDIT1: 现在,我已经试过这

-(void)animationLoop{ 

[UIView animateWithDuration:1.0 
        animations: ^{ myCircleUIView.transform = CGAffineTransformMakeTranslation([self randomFloatingGenerator], [self randomFloatingGenerator]); } 
        completion: 
    ^(BOOL finished) { 
     [UIView animateWithDuration:1.0 
          animations:^{ myCircleUIView.transform = CGAffineTransformMakeTranslation(0,0); 
          } 
          completion: 
      ^(BOOL finished) {[self animationLoop];}]; 
    }]; 

但它仍然没有工作,在动画....嗳哟......我想我做了一些愚蠢的错误,我需要第二组眼睛帮助我。

EDIT2: 修正了它。

-(void)animationLoop{ 
    CGPoint oldPoint = CGPointMake(myCircleUIView.frame.origin.x, myCircleUIView.frame.origin.y); 
    [UIView animateWithDuration:1.0 
        animations: ^{ myCircleUIView.frame = CGRectMake(myCircleUIView.frame.origin.x + [self randomFloatingGenerator], myCircleUIView.frame.origin.y + [self randomFloatingGenerator], myCircleUIView.frame.size.width, myCircleUIView.frame.size.height); } 
        completion: 
    ^(BOOL finished) { 
     [UIView animateWithDuration:1.0 
          animations:^{ myCircleUIView.frame = CGRectMake(oldPoint.x, oldPoint.y, myCircleUIView.frame.size.width, myCircleUIView.frame.size.height);} 
          completion: 
      ^(BOOL finished) {[self animationLoop];}]; 
    }]; 
} 

感谢您的帮助。

EDIT 3:

有人张贴增强的代码。

+0

使用的NSTimer并调用上面它的代码... – 2014-09-10 11:06:10

回答

5

@ Shamy的解决方案,改进,固定和CPU安全。

-(void)animateFloatView:(UIView*)view{ 

    // Abort the recursive loop 
    if (!view) 
     return; 

    CGPoint oldPoint = CGPointMake(view.frame.origin.x, view.frame.origin.y); 
    [UIView animateWithDuration:0.6 
        animations: ^{ view.frame = CGRectMake(view.frame.origin.x, view.frame.origin.y - 15, view.frame.size.width, view.frame.size.height); } 
        completion: 
    ^(BOOL finished) { 

     if (finished) { 
      [UIView animateWithDuration:0.6 
           animations:^{ view.frame = CGRectMake(oldPoint.x, oldPoint.y, view.frame.size.width, view.frame.size.height);} 
           completion: 
       ^(BOOL finished2) { 
        if(finished2) 
         [self animateFloatView:view]; 
       }]; 

     } 
    }]; 
} 

每当你想停止(离开视图控制器在必要时)的动画,拨打使用功能,因为这样:

[self recursiveFloatingAnimation:nil]; 

不回采动画将导致递归循环无限运行并压倒CPU堆栈。

1

它会表现得那样。当你重复动画而不是函数。所以每次你第一次打电话时它都会重复同样的动画。这样做:

@interface AAViewController() 

@property (nonatomic, strong) UIView * floatingView; 
@end 

@implementation AAViewController 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    // Do any additional setup after loading the view, typically from a nib. 
    _floatingView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 50, 50)]; 
    [_floatingView setBackgroundColor:[UIColor redColor]]; 
    [self.view addSubview:_floatingView]; 

    [self circleUIViewFloating]; 
} 

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

#pragma mark - Circle UIView floating 

- (void) circleUIViewFloating { 

    [UIView animateWithDuration:2.0 
        animations:^{ 
         _floatingView.transform = CGAffineTransformMakeTranslation([self randomFloatingGenerator : 270], [self randomFloatingGenerator:480]); 
        } completion:^(BOOL finished) { 
         [self circleUIViewFloating]; 
        }]; 
} 

- (int) randomFloatingGenerator : (int) max{ 
    return arc4random() % max; 
} 

这是complete running project为此。

+0

这里的问题是,它的翻译对象,所以当它完成时,它的位置不是它的起始位置,而是它转换的位置。我不想翻译这个对象,我只想对它进行动画处理。如果我使用重新注册,它将继续跳跃,如果我不使用它,它将保持自己浮动,而不是像我正在尝试的那样围绕其原始坐标浮动。 – Shamy 2014-09-10 15:38:58

+0

我不确定你实际想要达到什么.. – rptwsthi 2014-09-10 15:54:02

+0

类似于编辑。 – Shamy 2014-09-15 11:21:33

0
-(void)animationLoop{ 
CGPoint oldPoint = CGPointMake(myCircleUIView.frame.origin.x, myCircleUIView.frame.origin.y); 
[UIView animateWithDuration:1.0 
       animations: ^{ myCircleUIView.frame = CGRectMake(myCircleUIView.frame.origin.x + [self randomFloatingGenerator], myCircleUIView.frame.origin.y + [self randomFloatingGenerator], myCircleUIView.frame.size.width, myCircleUIView.frame.size.height); } 
       completion: 
^(BOOL finished) { 
    [UIView animateWithDuration:1.0 
         animations:^{ myCircleUIView.frame = CGRectMake(oldPoint.x, oldPoint.y, myCircleUIView.frame.size.width, myCircleUIView.frame.size.height);} 
         completion: 
     ^(BOOL finished) {[self animationLoop];}]; 
}]; 
} 
+0

此递归解决方案阻止主线程。除非您在离开VC之前停止使用此解决方案,否则我极力不鼓励使用此解决方案。另外,您需要在再次调用之前检查当前动画是否准备就绪,否则您将进入无限循环。 – Sebyddd 2015-03-13 16:33:13

1

雨燕2.1版本在这里:

func animateFloatView(view: UIView?) { 
    // Abort the recursive loop 
    guard let view = view else { return } 


    let oldPoint: CGPoint = CGPointMake(view.frame.origin.x, view.frame.origin.y) 
    UIView.animateWithDuration(0.6, animations: {() -> Void in 
     view.frame = CGRectMake(view.frame.origin.x, view.frame.origin.y - 15, view.frame.size.width, view.frame.size.height) 
     }, completion: {(finished: Bool) -> Void in 
      if finished { 
       UIView.animateWithDuration(0.6, animations: {() -> Void in 
        view.frame = CGRectMake(oldPoint.x, oldPoint.y, view.frame.size.width, view.frame.size.height) 
        }, completion: {(finished2: Bool) -> Void in 
         if finished2 { 
          self.animateFloatView(view) 
         } 
       }) 
      } 
    }) 
} 
0

雨燕3.1:

func animateFloatView(_ view: UIView?) { 
    guard let view = view else { return } 
    let oldYCoordinate = view.center.y 

    UIView.animate(withDuration: 0.6, animations: { 
     view.center.y -= 15 
    }, completion: { _ in 
     UIView.animate(withDuration: 0.6, animations: { 
      view.center.y = oldYCoordinate 
     }, completion: { _ in 
      self.animateFloatView(view) 
     }) 
    }) 
}