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, UIViewalt 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 UIViewbiri 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 CADisplayLinkgeri arama gibi) . Bizim displayNow()yöntem söyleyecektir CALayeriç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ü CALayers yapmaktan daha fazla çizim işlevselliği ortaya çıkar - UIViewkatmanlar, 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). CALayerDelegateProtokolün doğru kullanımı tüm bunları mümkün kılar.
Bir konfigürasyon hakkında daha fazla bilgi CALayers bulunabilir Çekirdek Animasyon Programlama Kılavuzu bölümüne Nesneleri Katmanı Yukarı Ayar .