强制视图同步绘制 (在返回调用代码之前)的保证退款、钢筋混凝土的方法是配置CALayer' 与您的UIView子类的交互。
在你的 UIView 子类中,创建一个displayNow()方法来告诉图层“<em>设置显示路线”然后“<em>让它这样”:
迅速
/// 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];
}
还要实现一个draw(_: CALayer, in: CGContext)方法,该方法将调用您的私有/内部绘图方法(因为 everyUIView是 a ,所以该方法有效CALayerDelegate):
迅速
/// 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();
}
并创建您的自定义internalDraw(_: CGRect)方法以及故障安全draw(_: CGRect):
迅速
/// 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];
}
现在只需myView.displayNow()在您真正需要它绘制时调用(例如从CADisplayLink回调中)。我们的displayNow()方法将告诉CALayerto displayIfNeeded(),这将同步回调到我们的draw(_:,in:)并进行绘图internalDraw(_:),在继续之前用绘制到上下文中的内容更新视觉。
这种方法类似于@RobNapier 上面的方法,但优点是调用displayIfNeeded()除了setNeedsDisplay(),这使得它是同步的。
这是可能的,因为CALayers 比 s 暴露了更多的绘图功能UIView——层比视图低级,并且明确设计用于在布局中进行高度可配置的绘图,并且(就像 Cocoa 中的许多东西一样)被设计为灵活使用(作为父类,或作为委托人,或作为与其他绘图系统的桥梁,或仅靠它们自己)。正确使用CALayerDelegate协议使这一切成为可能。
有关 s 的可配置性的更多信息CALayer可以在核心动画编程指南的设置层对象部分找到。