如何使用Core Animation创建无限滚动循环

时间:2015-01-09 19:38:37

标签: objective-c uiimageview

我是苹果开发的新手,对Core Animation有疑问,根据我的理解,你可以用对象/图像创建动画。

有很多教程,但它们都只显示代码,而不是真正解释它是如何工作的。因此,在我的应用程序中尝试使用Core Animation时,我遇到了一些困难。

我的目标是使用可填充图像创建一个永无止境的图像的幻觉。我对基本概念有所了解,我有2个UIImageViews设置,最初我尝试使用NSTimer每0.01秒调用2个方法来设置它们。一个人通过简单地在每次调用Y值时添加1来移动对象,另一个在每次调用时检查每个UIImageView的位置,然后当它到达允许它完全离开屏幕底部的像素时重置它到顶部,不幸的是它非常滞后,重置永远不会正常工作。

现在我转向Core Animation,因为我得到的印象是这是创建移动对象的预期方式。我用它对它的最小知识来创建一些动画,但我尝试过的任何东西都没有。

希望有人可以用两个UIImageViews帮我创建无限图像的错觉。我不介意你是否解释如何使用Core Animation制作一个,或者如果你想解决我写的原始代码的想法。

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

这是我掀起的样本UIViewController。它使用基本UIView实例而不是UIImageView,但这些实例应该是直接交换项。

在我的测试中,效果是一个永无止境的红色和蓝色横幅的外观(即视图控制器的白色背景从未见过)。

NOT 使用CAAnimation,而是使用为UIView提供的基于块的动画,我认为这更容易管理。

这会给你你想要的吗?

注意:这忽略了包含头文件ViewController.h,但它完全没有任何代码。

//  ViewController.m
#import "ViewController.h"

// Private Interface
@interface ViewController ()

#pragma mark -
#pragma mark - UI Controls
@property (strong, nonatomic) UIView *view1;
@property (strong, nonatomic) UIView *view2;

#pragma mark -
#pragma mark - Private Properties
@property (assign, nonatomic) BOOL isVisible;
@property (strong, nonatomic) NSLayoutConstraint *view1HeightConstraint;
@property (strong, nonatomic) NSLayoutConstraint *view2HeightConstraint;
@property (strong, nonatomic) NSLayoutConstraint *view1TopConstraint;
@property (strong, nonatomic) NSLayoutConstraint *view2TopConstraint;
@end

@implementation ViewController

#pragma mark -
#pragma mark - View Lifecycle
- (void)viewDidLoad {
    [super viewDidLoad];
    [self setupUserInterface];
}
- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    // At this point, self.view has its correct size,
    // so use it to set the height of the sub views
    self.view1HeightConstraint.constant = self.view.frame.size.height;
    self.view2HeightConstraint.constant = self.view.frame.size.height;

}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];

    // The screen has been shown, so store this value and begin the animations
    self.isVisible  = YES;
    [self slideDown1];
}

- (void)viewDidDisappear:(BOOL)animated {
    [super viewDidDisappear:animated];
    // So that the animations will stop and this view controller can be released
    self.isVisible  = NO;
}

#pragma mark -
#pragma mark - Animations
- (void)slideDown1 {
    // This sets the top of view1's frame equal to the bottom of self.view.frame
    self.view1TopConstraint.constant    = self.view.frame.size.height;
    // This sets the top of view2's frame equal to the top of self.view.frame
    self.view2TopConstraint.constant    = 0.0f;

    // If we didn't call this block, the changes set above would take effect "immediately"
    [UIView animateWithDuration:1.0f
                     animations:^{
                         // Calling this inside of an animation causes the changes above to be animated
                         [self.view layoutIfNeeded];
                     }
                     completion:^(BOOL finished) {
                         // This block will execute when the animations finish

                         // This moves self.view1 so that its bottom is aligned with the top of self.view
                         self.view1TopConstraint.constant   = -1.0f * self.view.frame.size.height;

                         // This causes the line above to take place immediately
                         [self.view layoutIfNeeded];

                         if (self.isVisible == YES) {
                             // If the screen is still visible, start the next animation
                             [self slideDown2];
                         }
                     }
     ];
}
- (void)slideDown2 {
    self.view1TopConstraint.constant    = 0.0f;
    self.view2TopConstraint.constant    = self.view.frame.size.height;
    [UIView animateWithDuration:1.0f
                     animations:^{
                         [self.view layoutIfNeeded];
                     }
                     completion:^(BOOL finished) {
                         self.view2TopConstraint.constant   = -1.0f * self.view.frame.size.height;
                         [self.view layoutIfNeeded];
                         if (self.isVisible == YES) {
                             [self slideDown1];
                         }
                     }
     ];
}
#pragma mark -
#pragma mark - UI Setup
- (void)setupUserInterface {
    [self createControls];
    [self setupControls];
    [self layoutControls];
}
- (void)createControls {
    self.view1  = [[UIView alloc] init];
    self.view2  = [[UIView alloc] init];
}
- (void)setupControls {
    self.view1.backgroundColor  = [UIColor redColor];
    // This line is required for our "full auto layout",
    // which just means (in this case) that we're doing it all in code
    [self.view1 setTranslatesAutoresizingMaskIntoConstraints:NO];

    self.view2.backgroundColor  = [UIColor blueColor];
    [self.view2 setTranslatesAutoresizingMaskIntoConstraints:NO];

}
- (void)layoutControls {
    // The subviews have to be added to self.view before we can constrain them
    [self.view addSubview:self.view1];
    [self.view addSubview:self.view2];

    // This sets up the subviews to make their width equal to self.view's width
    // You could have also used this method for the views' heights
    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.view1
                                                          attribute:NSLayoutAttributeWidth
                                                          relatedBy:NSLayoutRelationEqual
                                                             toItem:self.view
                                                          attribute:NSLayoutAttributeWidth
                                                         multiplier:1.0f
                                                           constant:0.0f]];
    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.view2
                                                          attribute:NSLayoutAttributeWidth
                                                          relatedBy:NSLayoutRelationEqual
                                                             toItem:self.view
                                                          attribute:NSLayoutAttributeWidth
                                                         multiplier:1.0f
                                                           constant:0.0f]];

    // This gives us properties we can use later to animate the views' movements
    self.view1TopConstraint     = [NSLayoutConstraint constraintWithItem:self.view1
                                                               attribute:NSLayoutAttributeTop
                                                               relatedBy:NSLayoutRelationEqual
                                                                  toItem:self.view
                                                               attribute:NSLayoutAttributeTop
                                                              multiplier:1.0f
                                                                constant:0.0f];
    // You created the constraint, but it has to be installed/added
    [self.view addConstraint:self.view1TopConstraint];

    // A different and probably less effective way to set the heights of the subviews
    self.view1HeightConstraint  = [NSLayoutConstraint constraintWithItem:self.view1
                                                               attribute:NSLayoutAttributeHeight
                                                               relatedBy:NSLayoutRelationEqual
                                                                  toItem:nil
                                                               attribute:NSLayoutAttributeNotAnAttribute
                                                              multiplier:1.0f
                                                                constant:0.0f];
    [self.view addConstraint:self.view1HeightConstraint];

    self.view2TopConstraint     = [NSLayoutConstraint constraintWithItem:self.view2
                                                               attribute:NSLayoutAttributeTop
                                                               relatedBy:NSLayoutRelationEqual
                                                                  toItem:self.view
                                                               attribute:NSLayoutAttributeTop
                                                              multiplier:1.0f
                                                                constant:0.0f];
    [self.view addConstraint:self.view2TopConstraint];

    self.view2HeightConstraint  = [NSLayoutConstraint constraintWithItem:self.view2
                                                               attribute:NSLayoutAttributeHeight
                                                               relatedBy:NSLayoutRelationEqual
                                                                  toItem:nil
                                                               attribute:NSLayoutAttributeNotAnAttribute
                                                              multiplier:1.0f
                                                                constant:0.0f];
    [self.view addConstraint:self.view2HeightConstraint];
}
@end