如何使[UIView animateWithDuration:..]在apportable的应用程序移植中工作?

时间:2013-11-17 04:17:22

标签: uiviewanimation apportable

在apportable的门户网站应用程序上,我需要通过调用来制作UIView *对象的一些动画(移动/缩放/更改alpha):

[UIView
 animateWithDuration:1.f
 delay:0.5f
 options:UIViewAnimationOptionAllowUserInteraction
 animations:^(void)
 {
     myview.center    = moveTo;
     myview.transform = transformTo;
     myview.alpha     = alphaTo;
 }
 completion:^(BOOL finished)
 {
     [self animationFinished];
 }];

现在它只会延迟,然后执行动画代码&完成代码。

2 个答案:

答案 0 :(得分:3)

谢谢你的回答。 但我需要动画“今天”,所以我下一堂课。 它的工作并不好,但它比没有好多了。 也许一个人会有所帮助

<强> AOTAnimate.h

//
//  AOTAnimate.h
//
//  Created by Andrei Bakulin on 18/11/2013.
//

#import <Foundation/Foundation.h>

@interface AOTAnimate : NSObject
{
    UIView          *view;

    NSInteger       animationTicksLeft;
    CGFloat         scaleX;
    CGFloat         scaleY;

    CGPoint         moveDelta;
    CGSize          scaleCurrent;
    CGSize          scaleDelta;
    CGFloat         alphaDelta;

    void (^completeAction)();
}

@property (nonatomic, assign)   CGFloat                 duration;
@property (nonatomic, assign)   CGFloat                 delay;
@property (nonatomic, assign)   CGFloat                 frequency;
@property (nonatomic, assign)   UIViewAnimationOptions  options;

@property (nonatomic, assign)   CGPoint                 moveFrom;
@property (nonatomic, assign)   CGAffineTransform       transformFrom;
@property (nonatomic, assign)   CGFloat                 alphaFrom;

@property (nonatomic, assign)   CGPoint                 moveTo;
@property (nonatomic, assign)   CGAffineTransform       transformTo;
@property (nonatomic, assign)   CGFloat                 alphaTo;

+ (AOTAnimate*)makeAnimationOnView:(UIView*)view_ duration:(CGFloat)duration_;
+ (AOTAnimate*)makeAnimationOnView:(UIView*)view_ duration:(CGFloat)duration_ delay:(CGFloat)delay_;

- (void)run;
- (void)runWithCompleteAction:(void (^)(void))complete_;

@end

<强> AOTAnimate.m

//
//  AOTAnimate.m
//
//  Created by Andrei Bakulin on 18/11/2013.
//

#import "AOTAnimate.h"

@implementation AOTAnimate

@synthesize duration, delay, frequency, options;
@synthesize moveFrom, transformFrom, alphaFrom;
@synthesize moveTo, transformTo, alphaTo;

+ (AOTAnimate*)makeAnimationOnView:(UIView*)view_ duration:(CGFloat)duration_
{
    return [self makeAnimationOnView:view_ duration:duration_ delay:0.f];
}

+ (AOTAnimate*)makeAnimationOnView:(UIView*)view_ duration:(CGFloat)duration_ delay:(CGFloat)delay_
{
    return [[AOTAnimate alloc] initWithView:view_ duration:(CGFloat)duration_ delay:(CGFloat)delay_];
}

//----------------------------------

- (void)dealloc
{
    [view release];

    if( completeAction )
        Block_release(completeAction);

    [super dealloc];
}

- (id)initWithView:(UIView*)view_ duration:(CGFloat)duration_ delay:(CGFloat)delay_
{
    self = [super init];
    if (self)
    {
        view            = [view_ retain];
        duration        = duration_;
        delay           = delay_;

        frequency       = 0.025f;
        options         = UIViewAnimationOptionAllowUserInteraction;

        moveFrom        = view.center;
        transformFrom   = view.transform;
        alphaFrom       = view.alpha;

        moveTo          = view.center;
        transformTo     = view.transform;
        alphaTo         = view.alpha;
    }
    return self;
}

//----------------------------------
#pragma mark - Run animation

- (void)run
{
    [self runWithCompleteAction:nil];
}

- (void)runWithCompleteAction:(void (^)(void))complete_
{
    view.center    = moveFrom;
    view.transform = transformFrom;
    view.alpha     = alphaFrom;

#ifndef ANDROID

    [UIView
     animateWithDuration:duration
     delay:delay
     options:options
     animations:^(void)
     {
         view.center    = moveTo;
         view.transform = transformTo;
         view.alpha     = alphaTo;
     }
     completion:^(BOOL finished)
     {
         if( complete_ )
             complete_();
     }];

#else

    if( duration <= 0.f )
    {
        [self doAnimationComplete];
        return;
    }

    animationTicksLeft = ceil( duration / frequency );

    if( animationTicksLeft == 0 )
    {
        [self doAnimationComplete];
        return;
    }

    moveDelta   = CGPointMake( (moveTo.x-moveFrom.x)/animationTicksLeft, (moveTo.y-moveFrom.y)/animationTicksLeft );
    alphaDelta  = (alphaTo-alphaFrom)/animationTicksLeft;

    CGSize scaleFrom = CGSizeMake( [self scaleX:transformFrom], [self scaleY:transformFrom] );
    CGSize scaleTo   = CGSizeMake( [self scaleX:transformTo],   [self scaleY:transformTo]   );

    scaleDelta  = CGSizeMake((scaleTo.width - scaleFrom.width)/animationTicksLeft,
                             (scaleTo.height - scaleFrom.height)/animationTicksLeft );

    scaleCurrent = scaleFrom;

    if( complete_ )
    {
        completeAction = Block_copy(complete_);
    }

    [self performSelector:@selector(doAnimationTick) withObject:nil afterDelay:delay];

#endif
}

//----------------------------------
#pragma mark - Manual animation

#ifdef ANDROID

- (void)doAnimationTick
{
    if( CGPointEqualToPoint( moveDelta, CGPointZero ) == NO )
    {
        view.center = CGPointMake( view.center.x + moveDelta.x, view.center.y + moveDelta.y );
    }

    if( CGSizeEqualToSize( scaleDelta, CGSizeZero) == NO )
    {
        view.transform = CGAffineTransformMakeScale( scaleCurrent.width, scaleCurrent.height );
        scaleCurrent.width  += scaleDelta.width;
        scaleCurrent.height += scaleDelta.height;
    }

    if( alphaDelta != 0.f )
    {
        view.alpha = view.alpha + alphaDelta;
    }

    // - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    animationTicksLeft--;

    if( animationTicksLeft > 0 )
    {
        [self performSelector:@selector(doAnimationTick) withObject:nil afterDelay:frequency];
    }
    else
    {
        [self doAnimationComplete];
    }
}

- (void)doAnimationComplete
{
    view.center    = moveTo;
    view.transform = transformTo;
    view.alpha     = alphaTo;

    if( completeAction )
        completeAction();
}

//----------------------------------
#pragma mark - Helpers

- (CGFloat)scaleX:(CGAffineTransform)t
{
    return sqrt(t.a * t.a + t.c * t.c);
}

- (CGFloat)scaleY:(CGAffineTransform)t
{
    return sqrt(t.b * t.b + t.d * t.d);
}

#endif

@end

像这样使用:

UIView *someview;

AOTAnimate *animate = [AOTAnimate makeAnimationOnView:someview duration:1.f delay:0.5f];

// allow to assign - animate.moveFrom / .tranfromFrom / alphaFrom properties,
// but by default they are copy from UIView* object

animate.moveTo      = CGPointMake( 100, 200 ); // new point where need to move
animate.transformTo = CGAffineTransformScale( CGAffineTransformIdentity, 1.5f, 1.5f );
animate.alphaTo     = 0.5f;

[animate runWithCompleteAction:^{
    NSLog(@"Animation done..);
}];

如果此方法将在iOS设备上运行 - 它将使用普通的[UIView animateWithDuration:...]方法

PS:这个班级只从一个中心点“移动”到另一个中心点。转换仅用于缩放对象(不移动)。我的2个测试设备上的Alpha不受支持,但可能会支持它。

答案 1 :(得分:0)

动画不适用于当前版本的Apportable的UIKit。不过,我们在UIKit的下一个版本中有完整功能的动画。一旦我们对质量和覆盖率感到满意,我们将发布。