Costique 제안에 따라 Core Graphics를 사용하여 내부 그림자를 그리는 방법을 궁금해하는 사람은 다음과 같습니다. (iOS에서 필요에 따라 조정)
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);
따라서 기본적으로 다음 단계가 있습니다.
- 경로 만들기
- 원하는 채우기 색상을 설정하고이 경로를 컨텍스트에 추가하고 컨텍스트를 채 웁니다.
- 이제 보이는 경로를 묶을 수있는 더 큰 직사각형을 만듭니다. 이 경로를 닫기 전에 보이는 경로를 추가하십시오. 그런 다음 경로를 닫아서 보이는 경로를 뺀 모양을 만듭니다. 이러한 경로를 만든 방법에 따라 채우기 방법 (짝수 / 홀수가 아닌 0이 아닌 감기)을 조사 할 수 있습니다. 본질적으로 하위 경로를 함께 더할 때 "빼기"를 얻으려면 시계 방향과 시계 반대 방향의 반대 방향으로 하위 경로를 그리거나 구성해야합니다.
- 그런 다음 보이는 경로를 컨텍스트의 클리핑 경로로 설정해야 화면 외부에 아무것도 그리지 않습니다.
- 그런 다음 오프셋, 흐림 및 색상을 포함하는 컨텍스트에 그림자를 설정합니다.
- 그런 다음 큰 모양에 구멍을 채우십시오. 색상은 중요하지 않습니다. 모든 것을 올바르게 수행했다면이 색상이 아닌 그림자 만 볼 수 있기 때문입니다.