Bir görünümü eşzamanlı olarak (çağıran koda dönmeden önce) çizmeye zorlamanın para iadesi garantili, güçlendirilmiş somut-sağlam yolu CALayer
, UIView
alt sınıfınızla olan etkileşimlerini yapılandırmaktır .
UIView alt sınıfınızda, displayNow()
katmana " görüntüleme için kursu ayarlamasını " ve ardından "böyle yapmasını " söyleyen bir yöntem oluşturun :
hızlı
/// Redraws the view's contents immediately.
/// Serves the same purpose as the display method in GLKView.
public func displayNow()
{
let layer = self.layer
layer.setNeedsDisplay()
layer.displayIfNeeded()
}
Objective-C
/// Redraws the view's contents immediately.
/// Serves the same purpose as the display method in GLKView.
- (void)displayNow
{
CALayer *layer = self.layer;
[layer setNeedsDisplay];
[layer displayIfNeeded];
}
Ayrıca draw(_: CALayer, in: CGContext)
, özel / dahili çizim yönteminizi çağıracak bir yöntem uygulayın (her UIView
biri a olduğu için çalışır CALayerDelegate
) :
hızlı
/// Called by our CALayer when it wants us to draw
/// (in compliance with the CALayerDelegate protocol).
override func draw(_ layer: CALayer, in context: CGContext)
{
UIGraphicsPushContext(context)
internalDraw(self.bounds)
UIGraphicsPopContext()
}
Objective-C
/// 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();
}
Ve internalDraw(_: CGRect)
hata korumalı özel yönteminizi oluşturun draw(_: CGRect)
:
hızlı
/// Internal drawing method; naming's up to you.
func internalDraw(_ rect: CGRect)
{
// @FILLIN: Custom drawing code goes here.
// (Use `UIGraphicsGetCurrentContext()` where necessary.)
}
/// For compatibility, if something besides our display method asks for draw.
override func draw(_ rect: CGRect) {
internalDraw(rect)
}
Objective-C
/// 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];
}
Ve şimdi myView.displayNow()
çekmeye gerçekten-gerçekten ihtiyaç duyduğunuzda arayın (örneğin bir CADisplayLink
geri arama gibi) . Bizim displayNow()
yöntem söyleyecektir CALayer
için displayIfNeeded()
eşzamanlı kızımız geri arayacak olan draw(_:,in:)
ve içinde çizim yapmak internalDraw(_:)
geçmeden önce bağlamında içine çizilmiş ilgilisana görsel güncelleyerek.
Bu yaklaşım @ RobNapier'in yukarısına benzer, ancak buna displayIfNeeded()
ek olarak arama avantajına da sahiptir setNeedsDisplay()
, bu da onu senkronize yapar.
Bu mümkündür, çünkü CALayer
s yapmaktan daha fazla çizim işlevselliği ortaya çıkar - UIView
katmanlar, görünümlerden daha düşük seviyededir ve mizanpaj içinde yüksek düzeyde yapılandırılabilir çizim amacıyla açıkça tasarlanmıştır ve (Cocoa'daki birçok şey gibi) esnek bir şekilde kullanılmak üzere tasarlanmıştır ( bir ana sınıf olarak veya bir delege olarak veya diğer çizim sistemlerine bir köprü olarak veya sadece kendi başlarına). CALayerDelegate
Protokolün doğru kullanımı tüm bunları mümkün kılar.
Bir konfigürasyon hakkında daha fazla bilgi CALayer
s bulunabilir Çekirdek Animasyon Programlama Kılavuzu bölümüne Nesneleri Katmanı Yukarı Ayar .