Это проблема, к которой я уже давно ухожу и возвращаюсь. Я никогда не решал эту проблему.
То, что я пытался сделать, использует CADisplayLink для динамического рисования прогресса стиля круговой диаграммы. Мой код работает нормально, когда у меня одновременно обновляется 1 - 4 интерфейса. Когда я добавляю что-то еще, рисунок пирогов становится очень резким.
Я хочу объяснить, что я пытался, в надежде, что кто-нибудь укажет на недостатки и предложит лучший метод рисования.
Я создаю 16 uiviews и добавляю подпредставление CAShapeLayer к каждому. Вот где я хочу нарисовать свои кусочки пирога.
Я предварительно вычислил 360 CGPath, представляющих круг от 0 до 360 градусов, и сохранил их в массиве, чтобы попытаться улучшить производительность.
В главном представлении я запускаю ссылку на дисплей, перебираю все мои другие представления, вычисляю, сколько должен отображаться полный круг, затем нахожу правильный путь и назначаю его моему слою фигур.
-(void)makepieslices
{
pies=[[NSMutableArray alloc]initWithCapacity:360];
float progress=0;
for(int i=0;i<=360;i++)
{
progress= (i* M_PI)/180;
CGMutablePathRef thePath = CGPathCreateMutable();
CGPathMoveToPoint(thePath, NULL, 0.f, 0.f);
CGPathAddLineToPoint(thePath, NULL, 28, 0.f);
CGPathAddArc(thePath, NULL, 0.f,0.f, 28, 0.f, progress, NO);
CGPathCloseSubpath(thePath);
_pies[i]=thePath;
}
}
- (void)updatePath:(CADisplayLink *)dLink {
for (int idx=0; idx<[spinnydelegates count]; idx++) {
id<SyncSpinUpdateDelegate> delegate = [spinnydelegates objectAtIndex:idx];
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[delegate updatePath:dLink];
});
}
}
- (void)updatePath:(CADisplayLink *)dLink {
dispatch_async(dispatch_get_global_queue(0, 0), ^{
currentarc=[engineref getsyncpercentForPad:cid pad:pid];
int progress;
progress = roundf(currentarc*360);
dispatch_async(dispatch_get_main_queue(), ^{
shapeLayer_.path = _pies[progress];
});
});
}
Эта техника просто не работает для меня, когда я пытаюсь одновременно обновлять более 4 или 5 пирогов одновременно. 16 обновлений экрана в одно и то же время звучат так, как будто для меня это не должно быть большим делом для iPad. Так что это заставляет меня думать, что я делаю что-то очень-очень неправильное.
Я был бы очень признателен, если бы кто-нибудь мог сказать мне, почему эта техника приводит к дрожащим обновлениям экрана, а также если бы они могли предложить другую технику, чтобы я мог провести исследование, которое позволит мне плавно выполнить 16 одновременных обновлений шейплайера.
РЕДАКТИРОВАТЬ Просто, чтобы дать вам представление о том, насколько плоха производительность, когда у меня все 16 пирогов на чертеже, процессор увеличивается до 20%
* РЕДАКТИРОВАТЬ *
Это основано на совете студентов, но я не вижу ничего нарисованного. сегментLayer является CGLayerRef как свойство моего кругового обзора.
-(void)makepies
{
self.layerobjects=[NSMutableArray arrayWithCapacity:360];
CGFloat progress=0;
CGContextRef context=UIGraphicsGetCurrentContext();
for(int i =0;i<360;i++)
{
progress= (i*M_PI)/180.0f;
CGLayerRef segmentlayer=CGLayerCreateWithContext(context, CGSizeMake(30, 30), NULL);
CGContextRef layerContext=CGLayerGetContext(segmentlayer);
CGMutablePathRef thePath = CGPathCreateMutable();
CGPathMoveToPoint(thePath, NULL, 0.f, 0.f);
CGPathAddLineToPoint(thePath, NULL, 28, 0.f);
CGPathAddArc(thePath, NULL, 0.f,0.f, 28, 0.f, progress, NO);
CGPathCloseSubpath(thePath);
[layerobjects addObject:(id)segmentlayer];
CGLayerRelease(segmentlayer);
}
}
-(void)updatePath
{
int progress;
currentarc=[engineref getsyncpercent];
progress = roundf(currentarc*360);
//shapeLayer_.path = _pies[progress];
self.pieView.segmentLayer=(CGLayerRef)[layerobjects objectAtIndex:progress];
[self.pieView setNeedsDisplay];
}
-(void)drawRect:(CGRect)rect
{
CGContextRef context=UIGraphicsGetCurrentContext();
CGContextDrawLayerInRect(context, self.bounds, segmentLayer);
}