iOS使用CGAffineTransformMakeTranslationg从一个视图的中心绘制虚线到另一个视图的中心动画第二个视图

时间:2015-01-22 16:06:01

标签: ios animation quartz-core

我想要建立一些具有挑战性的事情。

基本上,我在这里得到了这个场景:

scenario

由于Stackoverflow的回答,我可以绘制虚线:

Draw dotted (not dashed!) line, with IBDesignable in 2017

虚线绘图在里面完成:

-(void)drawRect:(CGRect)rect
{
    [self drawDottedLineFromStartingPoint:self.mainPhoto.center ToEndPoint:self.photo1.center];

    [self drawDottedLineFromStartingPoint:self.mainPhoto.center ToEndPoint:self.photo2.center];

    [self drawDottedLineFromStartingPoint:self.mainPhoto.center ToEndPoint:self.photo3.center];

    [self drawDottedLineFromStartingPoint:self.mainPhoto.center ToEndPoint:self.photo4.center];

    [self drawDottedLineFromStartingPoint:self.mainPhoto.center ToEndPoint:self.photo5.center];
}

-(void)drawDottedLineFromStartingPoint:(CGPoint)startPoint ToEndPoint:(CGPoint)endPoint
{
    UIBezierPath *path = [[UIBezierPath alloc] init];

    [path moveToPoint:startPoint];
    [path addLineToPoint:endPoint];
    path.lineWidth = 4;

    CGFloat dashes[] = {path.lineWidth * 0, path.lineWidth * 2};

    [path setLineDash:dashes count:2 phase:0];
    path.lineCapStyle = kCGLineCapRound;

    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGContextSetStrokeColorWithColor(ctx, [ThemeManager mediumTextColor].CGColor);

    [path stroke];
}

我面临的问题是,每个较小的圆圈都会通过落入到位来生成动画。

我为小圈子制作动画的方式是使用类似的东西:

CGAffineTransformMakeTranslation(0, 50);

当我这样做时,虚线从大圆圈绘制到较小圆圈的最终静止位置,虚线不会“跟随”较小的圆圈,因为它正在被动画并且掉落。

所以你看到的是:

wrong result

我想要实现的目标是否有任何简单的解决方案?我已经尝试过使用NSTimer和计算斜边长度,除以一个持续时间,但我没有走得太远:D

2 个答案:

答案 0 :(得分:2)

我不久前制作了一个应用程序,它做了类似于你想要的东西,所以我修改它做你想做的事情。我有一个名为NodeView的类,它只是一个带有一个属性的UIView子类,称为line,它是一个UIBezierPath(你可以将UIImageView子类化来做同样的事情)。我使用计时器来移动节点,并观察节点的中心属性,这样我就可以调用drawRect来描边节点的行。此版本逐个移动节点。我将控制器的视图设置为UIView的子类,这是该子类中的代码,

#import "RDView.h"
#import "NodeView.h"

@interface RDView ()
@property (weak, nonatomic) IBOutlet UIView *bigView; // this is equivalent to your large image view from which the other image views drop
@property (strong,nonatomic) NSMutableArray *paths;
@end

@implementation RDView


-(void)didMoveToWindow {
    self.bigView.layer.cornerRadius = self.bigView.frame.size.width/2.0;
    self.paths = [NSMutableArray new];
    self.nodes = [NSMutableArray new];
    for (int i = 0; i<5; i++) {
        NodeView *aNode = [NodeView new];
        CGFloat hue = arc4random_uniform(1000)/1000.0;
        aNode.backgroundColor = [UIColor colorWithHue:hue saturation:1 brightness:1 alpha:1.0];
        aNode.frame = CGRectMake(0, 0, 40, 40);
        [self.bigView layoutIfNeeded];
        aNode.center = self.bigView.center;
        [self addSubview:aNode];
        [self.nodes addObject:aNode];

        aNode.line = [UIBezierPath bezierPath];
        CGFloat dashes[] = {0, aNode.line.lineWidth * 4};
        [aNode.line setLineDash:dashes count:2 phase:0];
        aNode.line.lineCapStyle = kCGLineCapRound;
        [aNode.line moveToPoint:[self.bigView center]];
    }
    [self bringSubviewToFront:self.bigView];
    for (NodeView *aNode in self.nodes) {
        [aNode addObserver:self forKeyPath:@"center" options:NSKeyValueObservingOptionNew context:nil];
    }

    [self performSelector:@selector(dropNodes) withObject:nil afterDelay:1];
}

-(void)dropNodes {
    static int i = 0;
    [NSTimer scheduledTimerWithTimeInterval:.005 target:self selector:@selector(dropNode:) userInfo:@{@"nodeIndex":@(i)} repeats:YES];
    i++;
}

-(void)dropNode:(NSTimer *) timer {
    NSInteger i = [timer.userInfo[@"nodeIndex"] integerValue];
    NodeView *node = self.nodes[i];
    [node setCenter: CGPointMake(node.center.x + (i-2)*.25, node.center.y + 1)]; // spread the nodes out horizontally and move down
    [node.line addLineToPoint:node.center];
    if (node.center.y > 400) {
        [timer invalidate];
        if (i < self.nodes.count-1) {
            [self dropNodes];
        }
    }
}


-(void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    if ([keyPath isEqualToString:@"center"] ) {
        [self setNeedsDisplay];
    }
}


- (void)drawRect:(CGRect)rect {
    for (NodeView *aNode in self.nodes) {
        [aNode.line stroke];
    }
}

您可以在此处找到指向我的项目的链接http://jmp.sh/lIl5MXp

答案 1 :(得分:0)

我要感谢rdelmar启发我以及此链接告诉我有关视图的presentationLayer frame

ios observing change in frame of a UIView during animation

在这种情况下我没有使用KVO,但我确实使用NSTimer解决了我的问题并重新绘制了我的屏幕。

基本上我开始制作圆圈落下的动画后,我还会安排一个每0.01秒触发一次的NSTimer,并且回调方法会检查最终的圆形照片是否已完成动画,如果是,则使计时器无效:< / p>

-(void)showIntroAnimations
{
    self.hasBegunAnimating = YES;

    // start animating circle photos falling down

    [self setupObservers];
}

-(void)setupObservers
{
    [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(redrawLines:) userInfo:nil repeats:YES];
}

-(void)redrawLines:(NSTimer *)timer
{
    if([self.photo5.layer animationKeys].count > 0)
    {
        [self setNeedsDisplay];
    }
    else
    {
        [timer invalidate];
        timer = nil;
    }
}