[Mask 레이어 활용] 이미지 일부만 보여주기

아이폰 2013. 1. 22. 01:31



마스크 레이어를 활용하여 이미지의 일부부만 노출시키는 예제를 작성해 보았다. 


핵심은 마스크 레이어를 사용하면 터치 이벤트를 수신할 수 없기 때문에 


상위에 터치 이벤트를 수신하여 마스크 레이어 단에 이벤트를 전달해주는 투명뷰


덮는 것 !


간단한 예제인데 fx의 설리와 크리스탈을 배경  이미지로 사용하니 재미있는 예제가 됐다. 


(나도 이제 나이 들었나봐 ㅠㅜ 바라만 봐도 행복하구나 ㅋ)


아래는 예제를 실행한 사진이다. 





자! 이제 어떻게 예제를 구현했는지 알아보자!



구현방식을 간단히 그림으로 나타내 보면 아래와 같다. 





SBTouchView 를 완전히 투명하게 해서는 안된다. 완전히 투명할 경우에는 터치 이벤트를 수신하지 못하기 때문에 


투명도를 0.1로 하는 꼼수를 발휘했다.   SBTouchView는 터치 이벤트를 단순히 nextResponder 에게 전달하고, 


SBMaskedView가 그 이벤트를 받게되고, 마스크 영역을 이동시킨다. 


구현 절차는 아래와 같다. 


1. 마스크 레이어 설정 


maskLayer = [[CAShapeLayer layer] retain];
maskLayer.backgroundColor = [UIColor whiteColor].CGColor;
        
pathRect = CGRectMake(1, 1, 118, 118);
        
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:pathRect];
maskLayer.path = path.CGPath;
maskLayer.fillColor = [UIColor blackColor].CGColor;



핵심은 레이어의 배경색을 흰색으로 처리하고, 마스킹 시킬 영역(Path)만 검정색으로 칠하는 것입니다.





2. 배경레이어에 마스크 설정 

// 배경이미지 (크리스탈, 설리 이미지)
CALayer *bgLayer = [CALayer layer];

UIImage *bgImage = [UIImage imageNamed:@"christal.jpeg"];
bgLayer.frame = [self frameForImage:bgImage];
bgLayer.contents = (id)bgImage.CGImage;
bgLayer.mask = maskLayer;

[self.layer addSublayer:bgLayer];



배경(이미지) 레이어의 mask 속성에 마스크 레이어를 설정합니다.





3. 터치뷰를 설정 

// 터치 이벤트를 잡을 투명뷰 
SBTouchView *touchView = [[[SBTouchView alloc] initWithFrame:self.bounds] autorelease];
[self addSubview:touchView];

뷰의 최상위에 Touch Event를 가로챌 SBTouchView를 덮습니다. SBTouchView는 이벤트를 수신할 수 있게 
투명도를 0.1로 설정했습니다. 



// SBTouchView
@implementation SBTouchView

- (id)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        self.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.1];
    }
    return self;
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    [[self nextResponder] touchesBegan:touches withEvent:event];
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
    [[self nextResponder] touchesCancelled:touches withEvent:event];
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    [[self nextResponder] touchesEnded:touches withEvent:event];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    [[self nextResponder] touchesMoved:touches withEvent:event];
}


SBTouchView는 보시는 것처럼 nextResponder 에게 터치 이벤트를 전달합니다. 
그러면 아래에 있는 뷰가 이벤트를 받게됩니다.



4. 터치 이벤트를 수신하여 마스크 레이어 이동 시키기 


- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    CGPoint point = [touch locationInView:self];
    
    if (CGRectContainsPoint(pathRect, point)) {
        touchBegan = YES;
        touchPoint = point;
    }
}


- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    if (touchBegan) {
        UITouch *touch = [touches anyObject];
        CGPoint point = [touch locationInView:self];
        
        CGPoint destPoint = CGPointMake(pathRect.origin.x + (point.x - touchPoint.x),
                                 pathRect.origin.y + (point.y - touchPoint.y));

        pathRect.origin.x = destPoint.x;
        pathRect.origin.y = destPoint.y;
        UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:pathRect];
        maskLayer.path = path.CGPath;
        touchPoint = point;
    }
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    touchBegan = NO;
}



터치 영역이 마스크 레이어의 영역일 경우, 마스크 레이어의 위치를 이동시킵니다. 



소스 다운받기

Mask.zip




이상 마스크 레이어 사용법을 알아보면서 간단한 예제도 만들어 보았다. 


아이폰을 하면서 항상 느끼는 거지만...UI 프로그래밍이 생각보다 재밌다는 것!







  • ㅇㅈㅁ 2013.01.22 16:03 ADDR 수정/삭제 답글

    잘 배우고 갑니다 퍼갑니당!

    • 로그 @로그 2013.01.22 16:30 신고 수정/삭제

      ^^ 배우긴요~ 조금이라도 도움이 되셨으면 좋겠네요!