프로젝트를 진행하는 도중 버튼을 통해 뷰의 크기 및 회전을 조절해야하는 요구사항이 있었다.

처음에 간단하게 생각했던 부분이였는데 막상 구현하기 위해서 많은 시행착오가 있었다.

그 이유는 첫번째로 뷰의 transform에 대한 이해 부족이였고 두번째로는 크기 및 회전값을 버튼의 위치에 따라 구하는 것이 생각보다 어려웠다.

아래 함수가 버튼의 위치에 따른 크기 및 회전 값을 구하는 예제 이다.

- (void) touchBeginButton:(UIControl *)control withEvent:(UIEvent *)event {

    if([self pushHistory:NCDecoItemHistoryTypeZoomRotation] == YES){
        [self.delegate decoItem:self withEvent:NCDecoItemEventPushHistory];
    }
   
    i_PanGesture.enabled = NO;
   
    if(i_ButtonRotationAngle == -1){
       
        CGPoint rotationPoint = CGPointZero;
       
        rotationPoint.x = control.center.x - self.center.x;
        rotationPoint.y = control.center.y - self.center.y;
        
        i_ButtonRotationAngle = atan2f(rotationPoint.y, rotationPoint.x) * -1;
    }
   
    if(i_ButtonDistance == -1){
        
        i_ButtonDistance = NaDistanceBetweenTwoPoints(self.center, control.center);
    }

- (void) dragButton:(UIControl *) control withEvent: (UIEvent *) event  {
   
    CGPoint dragPoint = [[[event allTouches] anyObject] locationInView:self.superview];
   
    // 중점과 터치 포인트 간의 거리를 구하여 scale 값을 구한다.
    CGFloat distance = NaDistanceBetweenTwoPoints(self.center, dragPoint);
    
    CGFloat scale = distance / i_ButtonDistance;
   
    self.layer.transform = CATransform3DMakeScale(scale, scale, 1);
    
    // 회전 각을 구한다.
   
    CGPoint rotationPoint = CGPointZero;
   
    rotationPoint.x = dragPoint.x - self.center.x;
    rotationPoint.y = dragPoint.y - self.center.y;
    
    CGFloat angle = atan2f(rotationPoint.y, rotationPoint.x);
   
    // 핸들러의 위치만큼 앵글값을 더해준다.
    angle = i_ButtonRotationAngle + angle;
    
    self.layer.transform = CATransform3DRotate(self.layer.transform, angle, 0, 0, 1);
   
    [self.delegate decoItem:self withEvent:NCDecoItemEventHandlerReload];
}

 

뷰의 크기는 중학교 수준의 간단한 수학이 적용되면 되는데 이 것을 올바르게 적용하는 것이 힘들었다.

간단하게 요약하자면 버튼 이벤트가 시작될 때 핸들러 버튼의 위치를 통해 기준이 되는 반지름과 앵글 값을 얻는다.

이렇게 얻어진 값을 통해 드래그 이벤트가 일어날 때마다 드래그된 위치에 대한 반지름을 계산하여 기준 반지름에 대한 Scale 값을 구하고

드래그된 위치에 대한 angle값에 처음 구했던 버튼의 angle을 더해주어 변형되는 각을 보정해준다.

 

 

+ Recent posts