Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/111.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 将CADisplayLink更改同步到正在进行的CAAnimation_Ios_Core Animation_Caanimation_Cadisplaylink - Fatal编程技术网

Ios 将CADisplayLink更改同步到正在进行的CAAnimation

Ios 将CADisplayLink更改同步到正在进行的CAAnimation,ios,core-animation,caanimation,cadisplaylink,Ios,Core Animation,Caanimation,Cadisplaylink,我正在尝试将CADisplayLink和CAAnimation结合起来,这样我就可以用CAAnimation设置一些层的动画,并根据动画层中不断变化的表示层实时调整其他层。我意识到CAAnimations是在我的进程之外驱动的,而CADisplayLink回调在我的进程中,所以同步永远不会是完全紧密的。然而,我希望它会比我看到的更好(我看到的可能是4帧的延迟) 归结为一个简单的示例代码,我创建了一组成对的层。其中一半是轮廓,另一半是实心正方形-所有项目的大小相同。目标是为这些矩形对设置动画,使其

我正在尝试将CADisplayLink和CAAnimation结合起来,这样我就可以用CAAnimation设置一些层的动画,并根据动画层中不断变化的表示层实时调整其他层。我意识到CAAnimations是在我的进程之外驱动的,而CADisplayLink回调在我的进程中,所以同步永远不会是完全紧密的。然而,我希望它会比我看到的更好(我看到的可能是4帧的延迟)

归结为一个简单的示例代码,我创建了一组成对的层。其中一半是轮廓,另一半是实心正方形-所有项目的大小相同。目标是为这些矩形对设置动画,使其轮廓和正方形始终在一起(即,同一帧)

每个周期,我都为实体层设置一个新位置,并让CADisplayLink回调根据其补充实体层的表示层位置设置轮廓层。在模拟器上,这似乎在大部分时间都有效,至少在少数层上有效。一旦我得到了24对图层,一些轮廓开始滞后。在设备(iPadAir和iPhone6)上,即使只有一个正方形,轮廓也会滞后。我正在做iOs 8的所有测试

下面是我的ViewController实现

@implementation ViewController
{
    CADisplayLink *_displayLink;
    NSUInteger _startingLayerIndex;
}
#define NUMLAYERS 1

- (void)viewDidLoad {
    [super viewDidLoad];
    _startingLayerIndex = self.view.layer.sublayers.count;

    for (int i=0; i<NUMLAYERS; ++i) {
        CALayer *outlineLayer = [[CALayer alloc] init];
        outlineLayer.borderColor = [[UIColor blackColor] CGColor];
        outlineLayer.borderWidth = 1.0;
        CALayer *fillLayer = [[CALayer alloc] init];
        fillLayer.backgroundColor = [[UIColor redColor] CGColor];
        {
            CGRect r = CGRectMake(self.view.center.x, self.view.center.y, 0, 0);
            r = CGRectInset(r, -22, -22);
            outlineLayer.frame = r;
            fillLayer.frame = r;
        }

        [self.view.layer addSublayer:fillLayer];
        [self.view.layer addSublayer:outlineLayer];
    }

    UITapGestureRecognizer *gr = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onTap:)];
    [self.view addGestureRecognizer:gr];

    // WARNING - will create an ARC cycle. I don't care though, throwaway code
    _displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(refreshDisplay:)];
    [_displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
    [_displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
    [_displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:UITrackingRunLoopMode];
    _displayLink.paused = true;
}

-(void) refreshDisplay:(CADisplayLink *) displayLink {
    [CATransaction begin];
    [CATransaction setDisableActions:true];
    bool keepGoing = false;
    for (int i=0; i<NUMLAYERS; ++i) {
        CALayer *animatedLayer = [self.view.layer.sublayers objectAtIndex:(2*i)+_startingLayerIndex];
        if (animatedLayer.animationKeys.count) {
            keepGoing = true;
        }
        CALayer *trackingLayer = [self.view.layer.sublayers objectAtIndex:(2*i)+_startingLayerIndex+1];
        trackingLayer.position = [animatedLayer.presentationLayer position];
    }
    _displayLink.paused = !keepGoing;
    [CATransaction commit];
}

CGFloat randInRange(CGFloat r) {
    return (rand()%((int)r*2))/2.0;
}

-(void) onTap:(UITapGestureRecognizer *) gr {
    _displayLink.paused = false;
    [CATransaction begin];
    [CATransaction setAnimationDuration:2.0];
    //[CATransaction setAnimationTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]];
    for (int i=0; i<NUMLAYERS; ++i) {
        CGSize sz = self.view.frame.size;
        CGPoint p = CGPointMake(randInRange(sz.width), randInRange(sz.height));
        [[self.view.layer.sublayers objectAtIndex:(2*i)+_startingLayerIndex] setPosition:p];
    }
    [CATransaction commit];
}
@end
@实现视图控制器
{
CADisplayLink*\u显示链接;
NSUInteger(启动层索引);
}
#定义NUMLAYERS 1
-(无效)viewDidLoad{
[超级视图下载];
_startingLayerIndex=self.view.layer.sublayers.count;

对于(int i=0;抓取表示层的iDoes告诉我们屏幕上的内容与即将到来的更新推送到屏幕上时的内容相反?换句话说,响应CADisplayLink所做的工作是设置下一帧的工作,否?而表示层是关于当前显示帧的信息?