Гарантированный возврат денег, железобетонно-твердый способ принудительного просмотра синхронное рисование (до возврата к вызывающему коду) настроить взаимодействие CALayer
с вашим подклассом UIView
.
В своем подклассе UIView создайте метод - display
, который сообщает слою, что « да, он нуждается в отображении », а затем «, чтобы сделать его таким »:
/// Redraws the view's contents immediately.
/// Serves the same purpose as the display method in GLKView.
/// Not to be confused with CALayer's `- display`; naming's really up to you.
- (void)display
{
CALayer *layer = self.layer;
[layer setNeedsDisplay];
[layer displayIfNeeded];
}
Также реализуйте метод - drawLayer:inContext:
, который будет вызывать ваш собственный / внутренний метод рисования (который работает, поскольку каждый UIView является CALayerDelegate) :
/// Called by our CALayer when it wants us to draw
/// (in compliance with the CALayerDelegate protocol).
- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)context
{
UIGraphicsPushContext(context);
[self internalDrawWithRect:self.bounds];
UIGraphicsPopContext();
}
И создайте свой собственный метод - internalDrawWithRect:
вместе с отказоустойчивым - drawRect:
:
/// Internal drawing method; naming's up to you.
- (void)internalDrawWithRect:(CGRect)rect
{
// @FILLIN: Custom drawing code goes here.
// (Use `UIGraphicsGetCurrentContext()` where necessary.)
}
/// For compatibility, if something besides our display method asks for draw.
- (void)drawRect:(CGRect)rect {
[self internalDrawWithRect:rect];
}
А теперь просто звоните [myView display]
всякий раз, когда вам действительно нужно это нарисовать. - display
сообщит от CALayer
до displayIfNeeded
, который будет синхронно перезванивать в - drawLayer:inContext:
и выполнять рисование в - internalDrawWithRect:
, обновляя визуальный элемент с тем, что вписано в контекст, прежде чем двигаться дальше.
Этот подход похож на описанный выше @ RobNapier, но имеет преимущество вызова - displayIfNeeded
в дополнение к - setNeedsDisplay
, что делает его синхронным.
Это возможно, потому что CALayer
s предоставляет больше функциональных возможностей рисования, чем UIView
s - слои имеют более низкий уровень, чем представления, и разработаны специально для целей высоко настраиваемого рисования в макете и (как и многие другие вещи в Какао) предназначены для гибкого использования (в качестве родительского класса, или в качестве делегатора, или в качестве моста к другим системам рисования, или просто самостоятельно).
Дополнительную информацию о настраиваемости CALayer
s можно найти в разделе Настройка объектов слоя в Руководстве по программированию базовой анимации .