相关疑难解决方法(0)

UIScrollView暂停NSTimer直到滚动完成

当一个UIScrollView(或其派生类)滚动时,似乎所有NSTimers正在运行的都会暂停,直到滚动完成.

有办法解决这个问题吗?主题?优先级设置?什么?

uiscrollview nstimer ios

82
推荐指数
6
解决办法
2万
查看次数

在iPhone上拖动UIScrollView时,OpenGL ES视图中的动画会冻结

我有一个动画透明的OpenGL ES子视图(Apple的模板EAGLView类的修改),它绘制一个旋转的球体.就像Apple的例子一样,CADisplayLink用在可用的设备上.

在同一屏幕上,有一个UIScrollView包含可以选择的UIButtons.当用户滚动UIScrollView时,我的EAGLView的动画会冻结.此行为在iPhone 2G设备上的iOS模拟器4.2和iPhone OS 3.1.3上重现.

除了编写自己的滚动视图之外,还有任何关于如何防止EAGLView暂停的想法?

iphone opengl-es uiscrollview uikit

22
推荐指数
1
解决办法
9455
查看次数

如何更快地将视图渲染到图像中?

我正在制作放大镜应用程序,允许用户触摸屏幕并移动他的手指,将有一个放大镜与他的手指路径.我通过截屏实现它并将图像分配给放大镜图像视图,如下所示:

    CGSize imageSize = frame.size;
    UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0.0);
    CGContextRef c = UIGraphicsGetCurrentContext();
    CGContextScaleCTM(c, scaleFactor, scaleFactor);
    CGContextConcatCTM(c, CGAffineTransformMakeTranslation(-frame.origin.x, -frame.origin.y));
    [self.layer renderInContext:c];
    UIImage *screenshot = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return screenshot;
Run Code Online (Sandbox Code Playgroud)

问题是这个问题很self.layer renderInContext慢,因此用户在移动手指时感觉不顺畅.self.layer renderInContext然而,我试图在其他线程中运行,它使放大镜图像看起来很奇怪,因为放大镜中的图像显示延迟.

有没有更好的方法将视图渲染成图像?确实renderInContext:使用GPU?

core-graphics calayer uiview ios ios6

21
推荐指数
1
解决办法
2万
查看次数

为什么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
查看次数

如何在应用程序后台处理期间暂停并发OpenGL绘图?

应用程序转到后台后,必须立即停止调用OpenGL函数.但不知何故,当用户按下主页按钮时,所有停止OpenGL的努力都会失败并且我的应用程序经常(但并不总是)崩溃.

它崩溃了

异常类型:EXC_BAD_ACCESS代码:KERN_INVALID_ADDRESS位于0x1 libGPUSupportMercury.dylib gpus_ReturnNotPermittedKillClient

据我所知,如果你在应用程序不在前台后调用OpenGL函数,应用程序将崩溃,因为GPU不适用于应用程序.

使用OpenGL呈现的视图具有调度队列

self.drawingQueue = dispatch_queue_create("openglRenderQueue", DISPATCH_QUEUE_SERIAL);
Run Code Online (Sandbox Code Playgroud)

它必须与UIScrollView并行渲染.所以有一个GCD 信号量让队列等待UIScrollView.

self.renderSemaphore = dispatch_semaphore_create(1);
Run Code Online (Sandbox Code Playgroud)

我创建了一个CADisplayLink来更新runloop:

CADisplayLink *dl = [[UIScreen mainScreen] displayLinkWithTarget:self selector:@selector(update)];
[dl addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
self.displayLink = displayLink; 
Run Code Online (Sandbox Code Playgroud)

update方法在串行渲染队列上执行绘图计算异步,并使用信号量等待UIScrollView.它最终在主线程上提交同步.

- (void)update {
  dispatch_async(drawingQueue, ^{
    if (dispatch_semaphore_wait(renderSemaphore, DISPATCH_TIME_NOW) != 0) {
        return;
    }

    @autoreleasepool {
        [EAGLContext setCurrentContext:context];

        glBindFramebufferOES(GL_FRAMEBUFFER_OES, framebuffer);
        glViewport(0, 0, width, height);
        glMatrixMode(GL_MODELVIEW);
        glClear(GL_COLOR_BUFFER_BIT);
        glLoadIdentity();

        // Quickly grab the target game state for rendering
        GameState state = targetState;

        [sprite drawState:state];

        dispatch_sync(dispatch_get_main_queue(), ^{
            if ([self canRender]) { …
Run Code Online (Sandbox Code Playgroud)

concurrency opengl-es ios caeagllayer

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

OpenGL ES 2.0 iPhone - 在后台线程块主线程上渲染

我在后台线程上使用与主线程不同的EAGLContext渲染OpenGL上下文.

我使用这样的东西:

- (void)renderInBackground {
      EAGLContext *context = [[EAGLContext] alloc] init];
      [EAGLContext setCurrentContext:context];


       Rendering..
    }
Run Code Online (Sandbox Code Playgroud)

但是,即使这是在后台线程中执行,当使用重型着色器时,主线程也会被阻塞,并且UI会卡住.

为什么后台线程阻塞主线程?方法不同步.

iphone opengl-es opengl-es-2.0

3
推荐指数
1
解决办法
3051
查看次数

使用Grand Central Dispatch,如何检查是否已经运行了一个块?

我正在使用GCD从互联网上进行一些后台加载.除了有点瑕疵之外,这很有效.在我的应用程序中,我有3个选项卡,当单击任何选项卡时,GCD开始为相应的选项卡执行后台加载.如果用户决定从第一个选项卡转到第二个选项卡(当GCD开始下载第一个选项卡的数据时),然后再次返回第一个选项卡.GCD将启动另一个后台线程(即使第一个后台线程尚未完成下载数据).

那么有没有办法检查后台线程当前是否正在运行?因此,如果用户选择非常快速地来回切换标签(由于某种原因),它就不会启动多个后台线程.

iphone objective-c grand-central-dispatch ios

2
推荐指数
1
解决办法
1884
查看次数