Cách chắc chắn, được củng cố, cụ thể, chắc chắn để buộc chế độ xem vẽ đồng bộ (trước khi quay lại mã gọi) là để định cấu hình các CALayer
tương tác của UIView
lớp với lớp con của bạn .
Trong lớp con UIView của bạn, hãy tạo một displayNow()
phương thức cho lớp đó đến khóa học được thiết lập để hiển thị, sau đó chuyển sang làm cho nó trở nên thật :
Nhanh
/// 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()
}
Mục tiêu-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];
}
Đồng thời triển khai một draw(_: CALayer, in: CGContext)
phương thức sẽ gọi phương thức vẽ riêng tư / nội bộ của bạn (hoạt động vì mọi thứ UIView
là a CALayerDelegate
) :
Nhanh
/// 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()
}
Mục tiêu-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();
}
Và tạo internalDraw(_: CGRect)
phương thức tùy chỉnh của bạn , cùng với fail-safe draw(_: CGRect)
:
Nhanh
/// 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)
}
Mục tiêu-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];
}
Và bây giờ chỉ cần gọi myView.displayNow()
bất cứ khi nào bạn thực sự thực sự cần nó để vẽ (chẳng hạn như từ một CADisplayLink
cuộc gọi lại) . displayNow()
Phương pháp của chúng tôi sẽ nói CALayer
vớidisplayIfNeeded()
, mà đồng bộ sẽ gọi trở lại của chúng tôi draw(_:,in:)
và làm bản vẽ trong internalDraw(_:)
, cập nhật trực quan với những gì đang bị lôi kéo vào bối cảnh trước khi chuyển.
Cách tiếp cận này tương tự như @ RobNapier ở trên, nhưng có lợi thế là gọi displayIfNeeded()
thêm vào setNeedsDisplay()
, điều này làm cho nó đồng bộ.
Điều này là có thể bởi vì CALayer
s phơi bày nhiều chức năng vẽ hơn so với UIView
các lớp do lớp ở mức độ thấp hơn so với chế độ xem và được thiết kế rõ ràng cho mục đích vẽ có thể định cấu hình cao trong bố cục và (giống như nhiều thứ trong Ca cao) được thiết kế để được sử dụng linh hoạt ( như một lớp cha, hoặc như một đại biểu, hoặc là cầu nối đến các hệ thống vẽ khác, hoặc chỉ một mình). Việc sử dụng đúng CALayerDelegate
giao thức làm cho tất cả điều này có thể.
Thông tin thêm về khả năng cấu hình của CALayer
s có thể được tìm thấy trong phần Thiết lập đối tượng lớp của Hướng dẫn lập trình hoạt hình lõi .