2011-12-29 46 views
15

Nói tóm lại:Thiết khung đúng của một mới được tạo ra CAShapeLayer

  1. Apple không thiết lập các frame hay bounds cho một CAShapeLayer tự động (và Apple vẫn chưa thực hiện tương đương [UIView sizeThatFits])
  2. Nếu bạn đặt khung bằng cách sử dụng kích thước của hộp giới hạn của đường dẫn ... mọi thứ đều sai. Không có vấn đề làm thế nào bạn cố gắng thiết lập nó, nó vít lên con đường

Vì vậy, cách chính xác để lập trình thiết lập các khung hình của một mới tạo CAShapeLayer với một mới gia tăng CGPath là gì? Tài liệu của Apple im lặng về vấn đề này.

Những điều tôi đã cố gắng, mà không làm việc:

  1. Tạo một CAShapeLayer
  2. Tạo một CGPath, thêm nó vào lớp
  3. Kiểm tra của frame lớp - đó là {{0,0},{0,0}}
  4. Set: layer.frame = CGPathGetBoundingBox(layer.path)
  5. Khung giờ đã chính xác, nhưng đường dẫn bây giờ là DOUBLE offset - thay đổi frame làm cho đường dẫn đến hiệu quả được chuyển thêm (x,y) pixel

  6. Set: layer.bounds = CGPathGetBoundingBox(layer.path)

  7. ... nó mọi việc suôn sẻ hạt. Không có ý nghĩa gì nữa
  8. Hãy thử sửa lỗi bằng cách thực hiện layer.position = CGPathGetBoundingBox(layer.path).origin
  9. ... không có súc sắc; vẫn còn hạt.

Một điều tôi đã cố gắng mà DID làm việc, nhưng gây ra vấn đề ở đâu đó:

EDIT: điều này phá vỡ ngay sau khi bạn tự động xoay màn hình. Đoán của tôi: Việc tự động xoay của Apple yêu cầu phải kiểm soát thuộc tính "chuyển đổi".

  1. Tạo một CAShapeLayer
  2. Tạo một CGPath, thêm nó vào lớp
  3. Kiểm tra khung của lớp - đó là {{0,0},{0,0}}
  4. Set: layer.frame = CGPathGetBoundingBox(layer.path)
  5. Set: layer.transform = CGAffineTransformMakeTranslation(CGPathGetBoundingBox(layer.path).origin.x * -1, // same for y-coord: set it to "-1 * the path's origin

này hoạt động, nhưng ... rất nhiều mã của bên thứ ba giả định rằng biến đổi ban đầu f hoặc một số CALayer là Nhận dạng.

Nó không phải là khó khăn này! Chắc chắn có điều gì đó tôi đang làm sai ở đây?

(Tôi đã có một đề xuất: "mỗi khi bạn thêm đường dẫn, hãy chạy chức năng tùy chỉnh theo cách thủ công để chuyển tất cả các điểm theo -1 * (top-left-point.x, top-left-point.y)".Một lần nữa, nó hoạt động - nhưng nó phức tạp một cách lố bịch)

+0

Bạn đã bao giờ tìm được giải pháp cho điều này chưa? – jannej

+0

Chưa. Tôi hiện đang sử dụng giải pháp thay thế từ chính câu hỏi đó. Đó là chậm và một nỗi đau của nó để duy trì. Tôi nghĩ rằng vấn đề là một lỗi trong mã của Apple, có lẽ? – Adam

+3

Một phụ lục nhỏ: Cuối cùng tôi phát hiện ra rằng ".frame" không được Apple hỗ trợ. Điều này kỳ quái, bởi vì nó được sử dụng ở mọi nơi - nhưng nếu bạn đào sâu đủ trong tài liệu và/hoặc danh sách gửi thư của Apple, bạn sẽ khám phá các ghi chú từ các kỹ sư của Apple nói rằng nó không có ý định làm việc và họ sẽ không sửa lỗi với nó. Bạn đang mong đợi/bắt buộc phải sử dụng .bounds cho mọi thứ và xử lý .frame là "chỉ đọc". Vì vậy, nó đặc biệt mỉa mai rằng trong trường hợp này thiết lập .frame "gần như hoạt động", nơi thiết lập .bounds "không bao giờ hoạt động" :) – Adam

Trả lời

4

Đặt layer.bounds cho giới hạn đường dẫn là điều đúng để làm - bạn muốn làm cho không gian tọa độ cục bộ của lớp khớp với đường dẫn. Nhưng sau đó bạn cũng cần thiết lập thuộc tính vị trí của lớp để di chuyển nó vào đúng vị trí trong siêu lớp của nó.

(Thiết lập khung máy tính chuyển thành khung tính toán các giá trị đúng của .bounds và .position cho bạn, nhưng nó luôn để lại giới hạn. Không bị ảnh hưởng, đó không phải là những gì bạn muốn khi đường dẫn của bạn có nguồn gốc khác 0 .)

Vì vậy, một cái gì đó như thế này nên làm việc, giả sử bạn đã không thay đổi anchorPoint từ giá trị thông thường (0,5, 0,5) và muốn vị trí lớp tuôn về nguồn gốc của superlayer của nó:

CGRect r = CGPathGetBoundingBox(layer.path); 
layer.bounds = r; 
layer.position = CGPointMake(r.size.width*.5, r.size.height*.5);