iphone - 设置需求显示 : Too long between redraw cycles

标签 iphone ios objective-c xcode cocoa-touch

我是 cocoa 新手。我以为我可以将 UITableViewCell 背景 View 设置为我自己的自定义子类,以便在单元格的背景中显示加载栏,但当我想更新该栏时,调用 setNeedsDisplay 似乎不是这样足够快满足我的需要。现在我每 0.1 秒更新一次(我的意思是更新 UIView 中的数据,然后调用 setNeedsDisplay),并且每 30-40 秒才看到它实际更新一次。这是正常的吗?有什么办法可以加快速度吗?如果没有,我想做的事情还有其他选择吗?

这是我的绘制矩形代码(上面有一个辅助方法)和updateBarAt,这是调用它来更新它的代码:

-(void) updateBarAt: (float) playHead {
    self.playHead = playHead;
    NSLog(@"%f", self.playHead);
    [self setNeedsDisplay];
}

-(void) drawBackground: (CGRect) rect{
    double totalTime = self.playFor + self.wait;

    double waitPercentage = self.wait / totalTime;
    double playForPercentage = (self.playFor - self.fadeIn - self.fadeOut) / totalTime;
    double fadeInPercentage = self.fadeIn / totalTime;
    double fadeOutPercentage = self.fadeOut / totalTime;

    CGContextRef context = UIGraphicsGetCurrentContext();

    CGRect blueRect = CGRectMake((waitPercentage+fadeInPercentage)*rect.size.width, 0, playForPercentage*rect.size.width, rect.size.height);
    CGContextSetRGBFillColor(context, .639, .737, 1, 1.0);
    CGContextFillRect(context, blueRect);
    CGRect greenRect = CGRectMake(0, 0, waitPercentage*rect.size.width, rect.size.height);
    CGContextSetRGBFillColor(context, .843, 1, .651, 1.0);
    CGContextFillRect(context, greenRect);


    CGRect purpleRect = CGRectMake(waitPercentage*rect.size.width+.1, 0, fadeInPercentage*rect.size.width, rect.size.height);
    CGContextSetRGBFillColor(context, .7451, .639, 1.0, 1.0);
    CGContextFillRect(context, purpleRect);

    CGRect purpleR = CGRectMake((1.0 - fadeOutPercentage)*rect.size.width - .5, 0, fadeOutPercentage*rect.size.width + .5, rect.size.height);
    CGContextFillRect(context, purpleR);
}

- (void)drawRect:(CGRect)rect { //just does blue and green, need to add purple. Research
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetRGBFillColor(context, 1.0, 1.0, 1.0, 1.0);
    CGContextFillRect(context, rect);


    if (self.playHead == -1)
        return;
    [super drawRect:rect];

    double totalTime = self.playFor + self.wait;
    double playedPercentage = self.playHead / totalTime;

    double waitPercentage = self.wait / totalTime;
    double playForPercentage = (self.playFor - self.fadeIn - self.fadeOut) / totalTime;
    double fadeInPercentage = self.fadeIn / totalTime;
    double fadeOutPercentage = self.fadeOut / totalTime;

    NSLog(@"Played: %f Wait: %f Play: %f Fade In: %f Fade Out: %f", playedPercentage, waitPercentage, playForPercentage, fadeInPercentage, fadeOutPercentage);

    if (playedPercentage <= waitPercentage) {
        waitPercentage = playedPercentage;
        playForPercentage = 0;
        fadeInPercentage = 0;
        fadeOutPercentage = 0;
    } else if (playedPercentage <= waitPercentage+fadeInPercentage) {
        playForPercentage = 0;
        fadeInPercentage = playedPercentage - waitPercentage;
        fadeOutPercentage = 0;
    } else if (playedPercentage <= waitPercentage+fadeInPercentage + playForPercentage) {
        playForPercentage = playedPercentage - waitPercentage - fadeInPercentage;
        fadeOutPercentage = 0;
    } else {
        fadeOutPercentage = playedPercentage - waitPercentage - playForPercentage;
    }

    //[self drawBackground:rect];

    CGRect blueRect = CGRectMake((waitPercentage+fadeInPercentage)*rect.size.width, 0, playForPercentage*rect.size.width, rect.size.height);
    CGContextSetRGBFillColor(context, 0.0, 0.0, 1.0, 1.0);
    CGContextFillRect(context, blueRect);

    CGRect greenRect = CGRectMake(0, 0, waitPercentage*rect.size.width, rect.size.height);
    CGContextSetRGBFillColor(context, 0.0, 1.0, 0.0, 1.0);
    CGContextFillRect(context, greenRect);


    CGRect purpleRect = CGRectMake(waitPercentage*rect.size.width+.1, 0, fadeInPercentage*rect.size.width, rect.size.height);
    CGContextSetRGBFillColor(context, 0.33, 0.1, .55, 1.0);
    CGContextFillRect(context, purpleRect);

    CGRect purpleR = CGRectMake((1.0 - fadeOutPercentage)*rect.size.width - .5, 0, fadeOutPercentage*rect.size.width + .5, rect.size.height);
    CGContextFillRect(context, purpleR);
} 

最佳答案

大多数 UIKit 使用需要在主线程上完成。很可能您的 updateBarAt: 方法没有在主线程上被调用,这意味着您对 setNeedsDisplay 的调用正在某个后台线程上完成。

一种可能的解决方案是:

- (void)updateBarAt:(float)playHead {
    self.playHead = playHead;
    NSLog(@"%f", self.playHead);
    dispatch_async(dispatch_get_main_queue(), ^{
        [self setNeedsDisplay];
    });
}

另一种选择是将对 updateBarAt: 的调用包装在 dispatch_async 调用中。

关于iphone - 设置需求显示 : Too long between redraw cycles,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15696690/

相关文章:

iPhone 通过 POST 发送 Json 数组

iphone - iOS:由于 [OS_dispatch_data notifyDelegateOnWillFinish],应用程序崩溃?

iphone - iPhone 中基于选项卡栏的应用程序中的工具栏未显示在页面顶部

ios - UITableViewCONtroller 中的快速多个单元格子类

iphone - iOS:在代码中访问 app-info.plist 变量

objective-c - "Incompatible pointer..."将委托(delegate)分配给自己时发出警告

ios - 编辑 UITextField 时正在重置 UIScrollView

objective-c - 如何使用关闭按钮关闭 UIActionSheet 并避免崩溃?

再次按下 iOS 检查按钮

ios - 如何隐藏uiwebview导航按钮