-layoutSubviews
được gọi từ -layoutIfNeeded
nếu "bố trí cần thiết" cờ đã được thiết lập (sử dụng -setNeedsLayout
, hoặc tự động khi chế độ xem thay đổi giới hạn). Sử dụng nó để định vị
chế độ xem của bạn
[EDIT: Sử dụng nó để định vị subviews].
-drawRect:
được gọi từ -displayIfNeeded
nếu cờ "hiển thị cần thiết" được đặt (sử dụng -setNeedsDisplay
hoặc tự động nếu bạn đặt view.contentMode = UIViewContentModeRedraw
).
Cả hai -layoutIfNeeded
và -displayIfNeeded
được gọi tự động bởi UIKit/CoreAnimation trước khi mọi thứ được vẽ ra màn hình; bạn hiếm khi cần gọi trực tiếp cho họ.
Bạn có thể xác định vị trí của bạn trong subviews -drawRect:
(thậm chí bạn có thể thêm subviews!), Nhưng điều này là không khôn ngoan:
- Theo mặc định,
-setNeedsDisplay
không được gọi tự động vào một sự thay đổi giới hạn.
- Triển khai
-drawRect:
giảm hiệu suất (UIKit/CoreAnimation phải tạo ngữ cảnh đồ họa được bitmap hỗ trợ cho bạn); chỉ làm như vậy nếu bạn cần thực hiện bản vẽ tùy chỉnh.
- Bạn cần vẽ lại chế độ xem trong
-drawRect:
. Vẽ là tốn kém. Quan điểm di chuyển xung quanh là rẻ.
- UIKit/CoreAnimation có thể có một đường viền bố trí theo sau là một hình vẽ. CoreAnimation có thể sử dụng thông tin bố cục để quyết định xem những gì cần vẽ (ví dụ: nó có thể bỏ qua các chế độ xem bị che khuất bởi các chế độ xem mờ, lượt xem màn hình hoặc các bản xem trước bên ngoài giới hạn của clipToBounds = YES view; xem lớn). Nếu bạn di chuyển các khung nhìn trong khi vẽ, CoreAnimation có thể không vẽ chúng một cách chính xác.
EDIT: Và một số chi tiết hơn khi tôi tỉnh táo:
sự khác biệt giữa "hiển thị" và "vẽ" là gì? Việc hiển thị được thực hiện bởi -[CALayer display]
; triển khai mặc định là (khoảng)
- Nếu đại biểu của lớp phản hồi
-displayLayer:
, hãy gọi [self.delegate displayLayer:self]
.-displayLayer:
là nghĩa vụ phải thiết lập layer.content
đến (ví dụ) một CGImage,
- Ngược lại, nếu đại biểu của lớp đáp ứng
-drawLayer:inContext:
, thiết lập một bối cảnh bitmap hậu thuẫn, gọi [self.delegate drawLayer:self inContext:context]
, và lưu kết quả để layer.content
(đầu ra thực sự là một CABackingStore , có lẽ là một API riêng)
- Nếu không, không thay đổi
layer.content
.
Quan điểm là đại biểu của lớp, vì vậy bạn có thể thực hiện -[MyView displayLayer:]
thay vào đó, và làm công cụ thú vị như
self.layer.contents = (id)([UIImage imageNamed:@"foo"].CGImage)
(đó là khoảng những gì UIImageView làm)
- Một không-op, để ngăn chặn bất kỳ "bản vẽ" nào. Điều này có thể hữu ích nếu bạn đã phân lớp, ví dụ: UIToolbar và muốn cho nó một nền trong suốt. (Điều này cũng ngăn cản việc tạo CGContext/CABackingStore.)
- Di chuyển các bài đánh giá xung quanh mà không có hình phạt về hiệu suất (nhưng vẫn không phải là một ý tưởng hay vì những lý do trên).
Nguồn
2010-09-25 01:17:31
Câu trả lời hay. cảm ơn! – Idan