0

ココア初心者です。UITableViewCell バックグラウンド ビューを独自のカスタム サブクラスに設定して、セルのバックグラウンドにローディング バーを表示できるsetNeedsDisplayと思ったのですが、バーを更新したいときに呼び出すのは、私のニーズに対して十分に高速ではないようです。現在、私はそれを更新しています(つまり、UIViewのデータを更新してから呼び出すことを意味しますsetNeedsDisplay).1秒ごとに、実際の更新は30〜40秒ごとに表示されます。これは正常ですか?スピードアップする方法はありますか?そうでない場合、私がやろうとしていることに対する他のオプションはありますか?

これは、 draw rect (その上にヘルパー メソッドがあります) のコードと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);
} 
4

1 に答える 1

1

ほとんどのUIKit使用は、メイン スレッドで行う必要があります。ほとんどの場合、updateBarAt:メソッドはメイン スレッドで呼び出されていません。これは、への呼び出しがsetNeedsDisplayバックグラウンド スレッドで行われていることを意味します。

考えられる解決策の1つは次のとおりです。

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

updateBarAt:別のオプションは、呼び出しを呼び出しでラップすることdispatch_asyncです。

于 2013-03-29T03:52:38.207 に答える