【问题标题】:How to create an infinite scrolling loop with Core Animation如何使用 Core Animation 创建无限滚动循环
【发布时间】:2015-01-10 22:37:24
【问题描述】:

我是苹果开发的新手,有一个关于核心动画的问题,据我了解,它允许您使用对象/图像创建动画。

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

我的目标是使用可耕作的图像来创造永无止境的图像错觉。我对基本概念有所了解,我设置了 2 个 UIImageView,最初我尝试使用 NSTimer 每 0.01 秒调用 2 个方法来设置它们。一个移动对象只需在每次调用时将 Y 值加 1,另一个在每次调用时检查每个 UIImageView 的位置,然后当它到达允许它完全离开屏幕底部的像素时将其重置到顶部,不幸的是它非常滞后并且重置从未正常工作。

现在我转向核心动画,因为我觉得那是创建移动对象的预期方式。我已经用我对它的最小知识来创建一些动画,但我尝试过的都没有真正奏效。

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

非常感谢任何帮助。

【问题讨论】:

    标签: objective-c uiimageview


    【解决方案1】:

    这是我制作的UIViewController 示例。它使用基本的UIView 实例而不是UIImageView,但那些应该是直接交换项。

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

    使用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
    

    【讨论】:

    • 谢谢,我还没有尝试过代码,但它看起来应该可以满足我的需求。您能否在代码中添加一些 cmets,因为在某些时候我需要稍微更改代码以适应我正在尝试设计的游戏,并且由于我对 Objective-c 的基本知识,我不完全理解什么每个部分都有,尤其是约束(我已经从主情节提要设置了约束)以及您设置的所有属性。如果可以的话,那就太好了:)谢谢
    猜你喜欢
    • 1970-01-01
    • 2020-07-14
    • 2012-04-27
    • 1970-01-01
    • 1970-01-01
    • 2014-04-26
    • 2017-01-17
    • 1970-01-01
    • 2021-02-20
    相关资源
    最近更新 更多