2014년 9월 12일 금요일

[iOS] 물방울 모양의 UIView를 만들자.

UIView의 모양을 물방울 모양으로 변형을 해보겠습니다.

1. UIBezierPath를 이용해서, 물방울 모양의 Path를 만듭니다.

source code
- (UIBezierPath *)waterDropPath:(CGRect)frame
{
    //NSLog(@"makeWaterDropPathIn: %@", NSStringFromCGRect(frame) );
    float x = frame.origin.x;
    float y = frame.origin.y;
    float hW = frame.size.width/2.0f;
    float H = frame.size.height;
    
    CGPoint sp = CGPointMake(x+hW, y);      //Start point
    CGPoint cp = CGPointMake(x+hW, y+H-hW); //Center point
    
    CGPoint b1 = CGPointMake(x, y+H-hW);    //WaterDrop left point
    CGPoint c1 = CGPointMake(x+hW, y+hW+hW/2); //왼쪽 내려오는 부분에서 사용
    CGPoint c2 = CGPointMake(x, y+H-hW-hW);    
    CGPoint c3 = CGPointMake(x+hW+hW, y+H-hW-hW); //오른쪽 올라가는 부분에서 사용
    
    UIBezierPath *path = [[UIBezierPath alloc] init];
    [path setLineWidth:0.5f];
    
    [path moveToPoint:sp]; //시작점으로 이동
    
    [path addCurveToPoint:b1
             controlPoint1:c1
             controlPoint2:c2]; //왼쪽 물방울 내려오는 부분
    
    [path addArcWithCenter:cp
                     radius:hW//-0.5f
                 startAngle:DEGREE_TO_RADIAN(180)
                   endAngle:DEGREE_TO_RADIAN(0)
                  clockwise:NO]; //물방울 아래부분

    [path addCurveToPoint:sp
             controlPoint1:c3 
             controlPoint2:c1]; //오른쪽 올라가는 부분
    
    return path;
}

2. Path로 부터 현재 뷰의 layer의 mask를 설정합니다.

source code
- (void) setWaterDropClippingArea:(CGRect)frame
{
    //클립핑 영역을 만든다.
    [self setClippingAreaFromPath:[self waterDropPath:frame]];
}
- (void)setClippingAreaFromPath:(UIBezierPath *)path
{
    CAShapeLayer *mask = [CAShapeLayer layer];
    mask.path = path.CGPath;
    
    self.layer.mask = mask;
}

3. 결과물

 

 위 소스의 sp, cp, b1, c1, c2, c3 위치를 왼쪽에 표시하였습니다.