2012-03-19 22 views
9

Tôi muốn thêm một bóng xung quanh cạnh bên ngoài của một HOLLOW CGPath (hai từ này là quan trọng: bên ngoài + rỗng :)).Clipping shadows được tạo bởi CALayer.shadow

Việc triển khai bóng của Apple chỉ cho phép bạn thực hiện các bóng "lấp đầy".

Vậy ... làm thế nào để cắt bỏ phần bên trong của chính bóng? Nếu đó là một cuộc gọi kết xuất, tôi sẽ gọi các phương thức CGContextSetClip * để clip nó đến nơi tôi muốn ... nhưng tôi không thể thấy bạn sẽ nhận được nó như thế nào, vì nó không phải là một cuộc gọi kết xuất, cũng không phải là một bản thân CALayer .

(một hậu quả đáng tiếc của Apple "giấu" nó như là một tập hợp các biến kỳ diệu, tôi đoán?)

NB: đây là iOS chỉ - IIRC trên máy Mac, bạn có thể truy cập trực tiếp đến các bộ lọc sử dụng để tạo bóng tối , do đó bạn có thể tạo bóng của riêng bạn (tùy ý) bằng tay.


UPDATE:

tôi làm việc ra làm thế nào để cắt để chỉ hiển thị các phần bên trong của bóng: đặt "layer.mask", trở thành một layer mới đó là một bản sao của lớp hiện tại (tức là cùng một đường dẫn) và thiết lập đường dẫn fillcolor thành bất kỳ thứ gì có alpha đầy đủ.

Điều này trái ngược với những gì tôi đang cố gắng, vì vậy nếu tôi có thể tìm cách để lớp mặt nạ lật alpha (0 trở thành 1, 1 trở thành 0), tôi sẽ ở đó ...

Trả lời

5

Giả sử bạn có một phương pháp:

-(CAShapeLayer*) cloneShapeLayer; // creates a new CAShapeLayer and copies the values 

... sau đó làm điều này:

  1. Sao chép lớp, tạo ra "mặt nạ"
  2. Đưa những mặt nạ - cùng CGPath, hãy nhớ - và thay thế nó pa th với một con đường mà có:
    1. Các rect của cả lớp
    2. TRỪ đường dẫn gốc
    3. (đạt được bằng cách sử dụng quy tắc EO)
  3. thiết lập mặt nạ của lớp gốc (đường dẫn một với bóng) là lớp mới "mặt nạ"

tức trong mã:

CAShapeLayer* maskLayer = [originalLayer cloneShapeLayer]; 
// got to make it a bit bigger if your original path reaches to the edge 
// since the shadow needs to stretch "outside" the frame: 
CGFloat shadowBorder = 50.0; 
maskLayer.frame = CGRectInset(maskLayer.frame, - shadowBorder, - shadowBorder); 
    maskLayer.frame = CGRectOffset(maskLayer.frame, shadowBorder/2.0, shadowBorder/2.0); 
maskLayer.fillColor = [UIColor blackColor].CGColor; 
maskLayer.lineWidth = 0.0; 
maskLayer.fillRule = kCAFillRuleEvenOdd; 

CGMutablePathRef pathMasking = CGPathCreateMutable(); 
CGPathAddPath(pathMasking, NULL, [UIBezierPath bezierPathWithRect:maskLayer.frame].CGPath); 
CGAffineTransform catShiftBorder = CGAffineTransformMakeTranslation(shadowBorder/2.0, shadowBorder/2.0); 
CGPathAddPath(pathMasking, NULL, CGPathCreateCopyByTransformingPath(maskLayer.path, &catShiftBorder)); 
maskLayer.path = pathMasking; 

shapeLayer.mask = maskLayer; 

NB: điều này thực sự hoạt động, ngoại trừ cái bóng dường như được phóng to một chút so với khi tôi không che mặt nạ. Oh well.

+0

Tôi đã thử điều này, nhưng không có gì xảy ra với lớp của tôi và bạn không xác định 'shadowBorderWidth'. Điều đó nghĩa là gì? –

+0

Tôi đã thay đổi mã. Tôi không biết nếu nó vẫn sẽ làm việc, có lẽ sẽ. Nếu nó không làm việc cho bạn, bạn có rất nhiều sửa lỗi để làm: phương pháp cloneShapeLayer của bạn, quy tắc quanh co của bạn trong CGPath, bản gốc CGPath của bạn, vv ... điều này phụ thuộc rất nhiều vào mã nguồn CỦA BẠN và dữ liệu hình ảnh CỦA BẠN - Tôi không thể gỡ lỗi cho bạn. – Adam

+0

Cảm ơn bạn, tôi sẽ cố gắng này :) –

Các vấn đề liên quan