UIView 확대 축소 작업시
if (gesture.state == UIGestureRecognizerStateBegan || gesture.state == UIGestureRecognizerStateChanged) {
// 이전 scale과 gesture의 scale을 바탕으로 변위값을 계산 후 새로운 scale값을 계산함 - 최대, 최소 크기를 제한할 수 있다.
CGFloat currentScale = [[[gesture view].layer valueForKeyPath:@"transform.scale"] floatValue];
// Constants to adjust the max/min values of zoom
const CGFloat kMaxScale = 2.0;
const CGFloat kMinScale = 0.5;
CGFloat newScale = 1 - (i_PrevScale - [gesture scale]); // new scale is in the range (0-1)
newScale = MIN(newScale, kMaxScale / currentScale);
newScale = MAX(newScale, kMinScale / currentScale);
CGAffineTransform transform = CGAffineTransformScale([[gesture view] transform], newScale, newScale);
[gesture view].transform = transform;
i_PrevScale = [gesture scale];
}
if (gesture.state == UIGestureRecognizerStateBegan || gesture.state == UIGestureRecognizerStateChanged) {
// 이전 scale값을 바탕으로 변위값을 직접 입력하여 형태를 변환시킨다. (최대, 최소 지정 어려움)
self.layer.transform = CATransform3DScale(self.layer.transform, gesture.scale/i_PrevScale, gesture.scale/i_PrevScale, 1);
i_PrevScale = [gesture scale];
}
UIView 회전시
if (gesture.state == UIGestureRecognizerStateBegan || gesture.state == UIGestureRecognizerStateChanged)
{ // 회전각의 변위값을 입력하여 회전시킨다.
self.layer.transform = CATransform3DRotate(self.layer.transform, gesture.rotation-i_PrevRotation, 0, 0, 1);
i_PrevRotation = gesture.rotation;
}
if (gesture.state == UIGestureRecognizerStateBegan || gesture.state == UIGestureRecognizerStateChanged)
{ // Geusture부터 얻은 rotation 값을 직접 이력한다.
self.transform = CGAffineTransformMakeRotation(gesture.rotation);
i_PrevRotation = gesture.rotation;
}
Button Handler 로 Zoom, Rotation 사용시
-(void) reloadButtonPoint {
// 핸들러의 위치는 중점과 거리차로 scale을 구하기 때문에 반드시 원(반지름 = 뷰의 중간 길이)의 좌표내에 존재해야한다.
CGPoint center = i_FrameHandler.center;
CGFloat point = sqrtf(powf(CGRectGetMidX(self.bounds), 2.0)/2);
center.x = CGRectGetMidX(self.bounds) + point;
center.y = CGRectGetMidX(self.bounds) - point;
i_FrameHandler.center = 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/ CGRectGetMidX(self.bounds);
if(scale >= self.minimumZoomScale && scale <= self.maximumZoomScale){
[self.layer setValue:[NSNumber numberWithFloat:scale] forKeyPath:@"transform.scale"];
}
// 터치 포인트와 중점의 위치차를 구하여 아크탄젠트 값으로 angle값을 산출한다.
CGPoint rotationPoint = CGPointZero;
rotationPoint.x = dragPoint.x - self.center.x;
rotationPoint.y = dragPoint.y - self.center.x;
CGFloat angle = atan2f(rotationPoint.y, rotationPoint.x);
[self.layer setValue:[NSNumber numberWithFloat:angle] forKeyPath:@"transform.rotation.z"];
}
참고사항
뷰의 scale값을 지정할 때 아래의 두 방식을 사용한다.
1. 직접 key path의 값을 변경
[view.layer setValue:[NSNumber numberWithFloat:scale] forKeyPath:@"transform.scale"];
2. transform 프로퍼티 값을 계산하여 변경
view.transform = CGAffineTransformMakeScale(scale, scale);
여기에서 1번의 방법인 경우 뷰가 중첩된 상황 각각 scale값을 변경하게되면 오작동하는 경우가 발생하였다. 이럴 경우 1번과 2번 방법을 혼합하면 이런 문제를 피할수 있었다.
'iOS' 카테고리의 다른 글
UIView Transform 간단 정리 (0) | 2012.06.14 |
---|---|
하위 UIView위 특정 위치를 상위 UIView에서 좌표 얻어오기 (0) | 2012.05.17 |
UITableView Section 헤더 고정 현상 방지 (0) | 2012.05.03 |
IOS 설정바로가기 URL (0) | 2012.04.19 |
UIDocumentInteractionController을 통한 앱간 문서 전달 (0) | 2012.04.09 |