Đối với bất kỳ ai khác tự hỏi làm thế nào để vẽ một bóng bên trong bằng Core Graphics theo gợi ý của Costique, thì đây là cách: (trên iOS điều chỉnh khi cần thiết)
Trong phương thức drawRect: ...
CGRect bounds = [self bounds];
CGContextRef context = UIGraphicsGetCurrentContext();
CGFloat radius = 0.5f * CGRectGetHeight(bounds);
// Create the "visible" path, which will be the shape that gets the inner shadow
// In this case it's just a rounded rect, but could be as complex as your want
CGMutablePathRef visiblePath = CGPathCreateMutable();
CGRect innerRect = CGRectInset(bounds, radius, radius);
CGPathMoveToPoint(visiblePath, NULL, innerRect.origin.x, bounds.origin.y);
CGPathAddLineToPoint(visiblePath, NULL, innerRect.origin.x + innerRect.size.width, bounds.origin.y);
CGPathAddArcToPoint(visiblePath, NULL, bounds.origin.x + bounds.size.width, bounds.origin.y, bounds.origin.x + bounds.size.width, innerRect.origin.y, radius);
CGPathAddLineToPoint(visiblePath, NULL, bounds.origin.x + bounds.size.width, innerRect.origin.y + innerRect.size.height);
CGPathAddArcToPoint(visiblePath, NULL, bounds.origin.x + bounds.size.width, bounds.origin.y + bounds.size.height, innerRect.origin.x + innerRect.size.width, bounds.origin.y + bounds.size.height, radius);
CGPathAddLineToPoint(visiblePath, NULL, innerRect.origin.x, bounds.origin.y + bounds.size.height);
CGPathAddArcToPoint(visiblePath, NULL, bounds.origin.x, bounds.origin.y + bounds.size.height, bounds.origin.x, innerRect.origin.y + innerRect.size.height, radius);
CGPathAddLineToPoint(visiblePath, NULL, bounds.origin.x, innerRect.origin.y);
CGPathAddArcToPoint(visiblePath, NULL, bounds.origin.x, bounds.origin.y, innerRect.origin.x, bounds.origin.y, radius);
CGPathCloseSubpath(visiblePath);
// Fill this path
UIColor *aColor = [UIColor redColor];
[aColor setFill];
CGContextAddPath(context, visiblePath);
CGContextFillPath(context);
// Now create a larger rectangle, which we're going to subtract the visible path from
// and apply a shadow
CGMutablePathRef path = CGPathCreateMutable();
//(when drawing the shadow for a path whichs bounding box is not known pass "CGPathGetPathBoundingBox(visiblePath)" instead of "bounds" in the following line:)
//-42 cuould just be any offset > 0
CGPathAddRect(path, NULL, CGRectInset(bounds, -42, -42));
// Add the visible path (so that it gets subtracted for the shadow)
CGPathAddPath(path, NULL, visiblePath);
CGPathCloseSubpath(path);
// Add the visible paths as the clipping path to the context
CGContextAddPath(context, visiblePath);
CGContextClip(context);
// Now setup the shadow properties on the context
aColor = [UIColor colorWithRed:0.0f green:0.0f blue:0.0f alpha:0.5f];
CGContextSaveGState(context);
CGContextSetShadowWithColor(context, CGSizeMake(0.0f, 1.0f), 3.0f, [aColor CGColor]);
// Now fill the rectangle, so the shadow gets drawn
[aColor setFill];
CGContextSaveGState(context);
CGContextAddPath(context, path);
CGContextEOFillPath(context);
// Release the paths
CGPathRelease(path);
CGPathRelease(visiblePath);
Vì vậy, về cơ bản có các bước sau:
- Tạo con đường của bạn
- Đặt màu tô bạn muốn, thêm đường dẫn này vào ngữ cảnh và điền vào ngữ cảnh
- Bây giờ, hãy tạo một hình chữ nhật lớn hơn có thể ràng buộc đường dẫn nhìn thấy được. Trước khi đóng đường dẫn này, hãy thêm đường dẫn hiển thị. Sau đó, đóng đường dẫn, để bạn tạo một hình dạng với đường dẫn nhìn thấy được trừ đi. Bạn có thể muốn điều tra các phương pháp lấp đầy (cuộn không của chẵn / lẻ) tùy thuộc vào cách bạn tạo các đường dẫn này. Về bản chất, để các đường con "trừ" khi bạn cộng chúng lại với nhau, bạn cần vẽ chúng (hay đúng hơn là dựng chúng) theo các hướng ngược nhau, một chiều theo chiều kim đồng hồ và ngược chiều kim đồng hồ.
- Sau đó, bạn cần đặt đường dẫn hiển thị của mình làm đường cắt trên ngữ cảnh để bạn không vẽ bất cứ thứ gì bên ngoài nó ra màn hình.
- Sau đó, thiết lập bóng trên bối cảnh, bao gồm bù đắp, làm mờ và màu sắc.
- Sau đó, lấp đầy hình dạng lớn với lỗ trong đó. Màu sắc không quan trọng, bởi vì nếu bạn đã làm đúng mọi thứ, bạn sẽ không thấy màu này, chỉ là bóng.