标签: cadisplaylink

如何创建圆形物体进入和分离厚物质的效果

基于下面的图像(我使用不同颜色的圆和平面,所以他们可以看到,但最终颜色将是相同的),使用Swift和Spritekit,我试图创建一个圆形对象进入的效果厚物质(不一定是粘性的)并与厚物质分离.基本上,当圆形物体分离时,它会在形成圆形时从平坦表面拉开.我想使用图像动画帧,但由于对象是具有物理主体的SKSpriteNodes,因此这将使得对象与动画的碰撞非常困难.另一种方法是使用CAAnimation,但我不知道如何将这与SKSpriteNodes与物理实体结合起来.如何使用上述任何方法或不同方法创建此分离效果?

在此输入图像描述

UPDATE

下图显示了当圆形物体进入厚物质直至其浸没时,厚物质表面的变化.

在此输入图像描述

cadisplaylink sprite-kit swift

41
推荐指数
1
解决办法
1098
查看次数

在不同的屏幕上绘制可可会失去性能

我有一个基于文档的应用程序,其中每个文档都有一个带有NSScrollView的窗口,它只使用Cocoa进行一些(相当连续的)绘图.

要调用绘图,我使用的是CVDisplayLink,如下面的代码所示:

- (void)windowControllerDidLoadNib:(NSWindowController *) aController {
     //other stuff...
     [self prepareDisplayLink]; //For some reason putting this in awakeFromNib crashes
}

//Prep the display link.
- (void)prepareDisplayLink {
    CVDisplayLinkCreateWithActiveCGDisplays(&displayLink);
    CVDisplayLinkSetCurrentCGDisplay(displayLink, ((CGDirectDisplayID)[[[[[self windowForSheet]screen]deviceDescription]objectForKey:@"NSScreenNumber"]intValue]));
    CVDisplayLinkSetOutputCallback(displayLink, &MyDisplayLinkCallback, self);
}

//Callback to draw frame
static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp* now, const CVTimeStamp* outputTime, CVOptionFlags flagsIn, CVOptionFlags* flagsOut, void* displayLinkContext)
{
    NSAutoreleasePool *pool =[[NSAutoreleasePool alloc]init];
    CVReturn result = [(ScrollView*)displayLinkContext getFrameForTime:outputTime];
    [pool drain];
    return result;
}

//Drawing function:
- (CVReturn)getFrameForTime:(const CVTimeStamp*)outputTime
{
    [scrollView lockFocusIfCanDraw];
    [self addToCurrentPostion:(dist/time)*CVDisplayLinkGetActualOutputVideoRefreshPeriod(displayLink)]; …
Run Code Online (Sandbox Code Playgroud)

cocoa screen nsview core-video cadisplaylink

34
推荐指数
1
解决办法
1383
查看次数

镜像UIWebView的最佳方式

我需要将UIWebView的CALayers镜像到较小的CALayer.较小的CALayer本质上是较大的UIWebView的一部分.我很难做到这一点.唯一接近的是CAReplicatorLayer,但鉴于原始版本和副本必须将CAReplicatorLayer作为父级,我无法在不同的屏幕上拆分原件和副本.

我正在尝试做的一个例子:

在此输入图像描述

用户需要能够与较小的CALayer进行交互,并且两者都需要同步.

我尝试过使用renderInContext和CADisplayLink.不幸的是,有一些滞后/口吃,因为它试图重新绘制每一帧,每秒60次.我需要一种方法来进行镜像而无需在每个帧上重新绘制,除非实际发生了某些变化.所以我需要一种方法来了解CALayer(或儿童CALayers)何时变脏.

我不能简单地拥有两个UIWebView,因为两个页面可能不同(时间关闭,背景不同等等).我无法控制正在显示的网页.我也无法显示整个iPad屏幕,因为屏幕上还有其他元素不应显示在外部屏幕上.

较大的CALayer和较小的"pip"CALayer都需要在iOS 6中逐帧匹配.我不需要支持早期版本.

解决方案需要应用程序存储可通过.

uiwebview calayer ios cadisplaylink

23
推荐指数
2
解决办法
2023
查看次数

在Swift自定义动画中正确处理/清理CADisplayLink?

考虑使用这个简单的同步动画CADisplayLink,

var link:CADisplayLink?
var startTime:Double = 0.0
let animTime:Double = 0.2
let animMaxVal:CGFloat = 0.4

private func yourAnim()
    {
    if ( link != nil )
        {
        link!.paused = true
        //A:
        link!.removeFromRunLoop(
          NSRunLoop.mainRunLoop(), forMode:NSDefaultRunLoopMode)
        link = nil
        }

    link = CADisplayLink(target: self, selector: #selector(doorStep) )
    startTime = CACurrentMediaTime()
    link!.addToRunLoop(
      NSRunLoop.currentRunLoop(), forMode:NSDefaultRunLoopMode)
    }

func doorStep()
    {
    let elapsed = CACurrentMediaTime() - startTime

    var ping = elapsed
    if (elapsed > (animTime / 2.0)) {ping = animTime - elapsed}

    let frac = …
Run Code Online (Sandbox Code Playgroud)

animation cadisplaylink swift

19
推荐指数
2
解决办法
6278
查看次数

动画圆形UIBezierPath

我有一个项目,我根据设定的进度动画UIBezierPath.BezierPath呈圆形,位于UIView中,动画现在使用CADisplayLink在drawRect中完成.简单地说,根据设定的进度x,路径应径向延伸(如果x比之前大)或收缩(如果x更小).

self.drawProgress = (self.displayLink.timestamp - self.startTime)/DURATION;

CGFloat startAngle = -(float)M_PI_2;
CGFloat stopAngle = ((self.x * 2*(float)M_PI) + startAngle);
CGFloat currentEndAngle = ((self.oldX * 2*(float)M_PI) + startAngle);
CGFloat endAngle = currentEndAngle-((currentEndAngle-stopAngle)*drawProgress);

UIBezierPath *guideCirclePath = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:startAngle endAngle:endAngle clockwise:YES];
Run Code Online (Sandbox Code Playgroud)

这是x自我们上次更新以来收缩的情况.我遇到的问题实际上是一些:

  1. 形状始终以45º开始绘制(除非我旋转视图).我还没有找到任何方法来改变这一点,设置startAngle为-45º没有任何区别,因为它总是"弹出"到45.我有什么可以做的,或者我是否必须采用其他绘图方法?
  2. 有什么其他方式可以让这些东西动起来吗?我已经阅读了很多关于使用的内容,CAShapeLayer但我还没有完全理解使用这两种方法的实际差异(在缺点和好处方面).如果有人能澄清我会非常感激!

更新:我将代码迁移到CAShapeLayer,但现在我面临着另一个问题.最好用这张图片描述:

在此输入图像描述

发生的事情是,当层应该收缩时,薄的外线仍然存在(无论移动方向如何).当棒收缩时,x除非我明确地在其上形成新的白色形状,否则不会除去1-的Δ .这个代码如下.有任何想法吗?

UIBezierPath *circlePath = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:startAngle endAngle:stopAngle clockwise:YES];
CAShapeLayer *circle = [CAShapeLayer layer];
circle.path = [circlePath CGPath]; …
Run Code Online (Sandbox Code Playgroud)

core-animation objective-c ios cadisplaylink uibezierpath

17
推荐指数
1
解决办法
8191
查看次数

为什么UIScrollView会暂停我的CADisplayLink?

我有一个CAEAGLLayer支持的视图,它位于UIScrollView中.当我开始滚动时,调用openGL视图的-draw方法的CADisplayLink停止被调用.

我确认滚动时不会调用我的runloop启动/停止方法.一旦滚动开始,-draw方法就不会被调用,并且一旦滚动结束就恢复调用.

滚动开始后,UIKit是否会停止触发CADisplayLink?

显示链接被添加到运行循环中,如下所示:

[dl addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
Run Code Online (Sandbox Code Playgroud)

也许这个运行循环模式和UIScrollView存在冲突?是否存在其他运行循环模式或替代解决方案,即使在UIScrollView滚动时也能保持CADisplayLink触发?

我认为在任何应用程序中都不只有一个CADisplayLink.那是错的吗?

opengl-es uikit ios cadisplaylink caeagllayer

14
推荐指数
1
解决办法
2543
查看次数

如何正确停止和恢复CADisplayLink?

我发现了CADisplayLink的一个大问题.

我有最基本的EAGLLayer与OpenGL ES 1.1绘制旋转三角形进行测试.这需要以屏幕刷新率调用运行循环方法,所以我像这样启动runloop:

- (void)startRunloop {
    if (!animating) {
        CADisplayLink *dl = [[UIScreen mainScreen] displayLinkWithTarget:self selector:@selector(drawFrame)];
        [dl setFrameInterval:1.0];
        [dl addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
        self.displayLink = dl;

        animating = YES;
    }
}

- (void)stopRunloop {
    if (animating) {
        [self.displayLink invalidate];
        self.displayLink = nil;
        animating = NO;
    }
}
Run Code Online (Sandbox Code Playgroud)

当测试应用程序启动时,我调用-startRunloop.当我点击屏幕时,我调用-stopRunloop.当我再次点击时,我调用-startRunloop.等等.乒乓.

我正在测量在20秒内调用-drawFrame方法的频率,以及NSLog它.

  • FIRST启动/停止循环始终执行100%.我得到了最大帧速率.

  • 所有SUBSEQUENT启动/停止循环仅显示约80%的性能.我的帧速率要小得多.但是:总是几乎完全相同,+/ - 2帧.即使经过50次启动/停止循环后也没有进一步降级的倾向.

总结:像我上面那样创建CADisplayLink是好的,直到它失效或暂停.之后,任何新的CADisplayLink都不再表现良好.即使它是以与以前完全相同的方式创建的.如果我通过使用YES/NO调用-setPaused:方法暂停/恢复它也是如此.

我已经确定Allocations和VM Tracker Instruments没有内存管理问题.我还检查过CADisplayLink的-invalidate方法是否真的被调用了.

设备上的iOS 4.0(iPhone 4).

这是为什么?我错过了什么吗?

iphone performance ios cadisplaylink

13
推荐指数
4
解决办法
9915
查看次数

CADisplayLink目标选择器在失效后触发

我有一个CADisplayLink触发drawDirector对象中的方法.我想使CADisplayLink无效,然后取消分配Director对象使用的一些单独的Cache对象.draw方法不保留单例Cache对象.

stopAnimationDirector中调用的方法(此方法与方法无关draw),我做:

[displayLink invalidate];
Run Code Online (Sandbox Code Playgroud)

然后我开始发布单例Cache对象,但随后启动了CADisplayLink,draw最后一次调用该方法.这些draw方法试图访问解除分配的单例对象,一切都崩溃了.

这种情况有时只会发生:有时候应用程序不会崩溃,因为在displayLink实际失效并且draw方法已经完成运行后释放了Cache对象.

在使displayLink无效之后,我如何检查draw方法是否已经完成运行并且它不会再次触发,以便安全地使Cache对象无效?draw如果可能,我不想修改方法.

我尝试了很多组合,包括displayLink invalidate在主线程上执行使用

[self performSelectorOnMainThread:@selector(stopAnimation) withObject:self waitUntilDone:YES]

或尝试使用在currentRunLoop中执行它

[[NSRunLoop currentRunLoop] performSelector:@selector(stopAnimation) target:self argument:nil order:10 modes:[NSArray arrayWithObject:NSDefaultRunLoopMode]];

但结果总是一样的,有时它会过早地释放共享的Caches.

我也不想使用performSelector:withObject:afterDelay:任意延迟的方法.我想确保displayLink无效,draw方法结束,并且不会再次运行.

cocos2d-iphone ios cadisplaylink

9
推荐指数
1
解决办法
4441
查看次数

什么是Android相关的CADisplayLink(iOS)或CompositionTarget(WP)

我需要更新每帧我的动画,在iOS上我CADisplayLink,对我WinPhone有CompositionTarget,但我要如何做到这一点在Android?

目前我使用的是Timer旁边一个Handler,但我相信有一种方法来同步与刷新率回调.

android cadisplaylink

7
推荐指数
1
解决办法
1501
查看次数

使用Swift将实时秒表计时器格式化为百分之一秒

我有一个使用NSTimer以厘秒(0.01秒)更新间隔的应用程序,以字符串格式显示运行秒表为00:00.00(mm:ss.SS).(基本上克隆iOS内置秒表以集成到实时运动计时数学问题中,将来可能需要毫秒精度)

我使用(误用?)NSTimer来强制更新UILabel.如果用户按下Start,这是用于开始重复该功能的NSTimer代码:

displayOnlyTimer = NSTimer.scheduledTimerWithTimeInterval(0.01, target: self, selector: Selector("display"), userInfo: nil, repeats: true)
Run Code Online (Sandbox Code Playgroud)

这是由上面的NSTimer执行的函数:

func display() {
    let currentTime = CACurrentMediaTime() - timerStarted + elapsedTime

    if currentTime < 60 {
        timeDisplay.text = String(format: "%.2f", currentTime)
    }else if currentTime < 3600 {
        var minutes = String(format: "%00d", Int(currentTime/60))
        var seconds = String(format: "%05.2f", currentTime % 60)
        timeDisplay.text =  minutes + ":" + seconds
    }else {
        var hours = String(format: "%00d", Int(currentTime/3600))
        var minutes = String(format: "%02d", (Int(currentTime/60)-(Int(currentTime/3600)*60)))
        var seconds = String(format: …
Run Code Online (Sandbox Code Playgroud)

stopwatch time-format nstimer cadisplaylink swift

6
推荐指数
1
解决办法
1714
查看次数