强制视图同步绘制 (在返回调用代码之前)的保证退款、钢筋混凝土的方法是配置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()
方法将告诉CALayer
to displayIfNeeded()
,这将同步回调到我们的draw(_:,in:)
并进行绘图internalDraw(_:)
,在继续之前用绘制到上下文中的内容更新视觉。
这种方法类似于@RobNapier 上面的方法,但优点是调用displayIfNeeded()
除了setNeedsDisplay()
,这使得它是同步的。
这是可能的,因为CALayer
s 比 s 暴露了更多的绘图功能UIView
——层比视图低级,并且明确设计用于在布局中进行高度可配置的绘图,并且(就像 Cocoa 中的许多东西一样)被设计为灵活使用(作为父类,或作为委托人,或作为与其他绘图系统的桥梁,或仅靠它们自己)。正确使用CALayerDelegate
协议使这一切成为可能。
有关 s 的可配置性的更多信息CALayer
可以在核心动画编程指南的设置层对象部分找到。