2010-04-22 5 views
14

적용한 후 UIView의 크기를 가져옵니다 :어쩌면 내가 어떻게 든 간과 매우 간단한 일이다, 나는이 질문에 대한 답을 찾을 수 없습니다 놀랐습니다 CGAffineTransform

나는에 CGAffineTransform을 적용 후의 UIView의 실제 크기를 얻는 방법 그것?

예 :

내 UIView의 크기가 300 x 200 인 경우 스케일링 변환을 적용하여 수평 및 수직 모두 요소 2를 적용 해 봅니다. 이제 UIView는 화면에서 600 x 400을 차지하지만 경계선과 크기의 경계는 여전히 크기를 반환합니다. 300 x 200 ... UIView의 실제 크기는 어디에서 찾을 수 있습니까?

ps. 내가 uiview도 회전하고 싶다는 언급을 잊어 버렸습니다. 스케일링 만 적용하면 CGSizeApplyAffineTransform은 훌륭하게 작동하지만 회전이있을 경우 제대로 작동하지 않습니다.

편집 : drawnonward가 올바른 방향으로 절 지적, 난 그냥 컴파일 조금에게 코드를 세련되고 여기있다 :

UIView* view = (your view being transformed); 
CGAffineTransform trans = (view.transform or create a new transformation); 

CGRect rect = [view bounds]; 
CGMutablePathRef path = CGPathCreateMutable(); 
rect.origin = CGPointZero; 
CGPathAddRect(path , &trans , rect); 
rect = CGPathGetBoundingBox(path); 
CGPathRelease(path); 

지금 rect.size 변환과 뷰의 크기가 적용 포함 그려서 다시 감사드립니다

답변

11

[myView frame]은 레이아웃 및 관련 크기에 대해 부모에게 표시되는보기 프레임을 반환합니다. [myView bounds]은 그리기를 위해 뷰의 경계를 반환합니다. 여러보기에 적용된 변환이있는 경우보기에 또는보기에서 convertRect:을 사용할 수 있습니다.

편집 :

어쩌면 이렇게 될 수 있습니다.

CGRect rect = [view bounds]; 
CGPathRef path = CGPathCreateMutable(); 
rect.origin = CGPointZero; 
CGPathAddRect(rect , [view transform]); 
rect = CGPathGetBoundingBox(path); 
CGPathRelease(path); 

사용 [view center]는 수퍼에서 위치를 찾을 수 있습니다. 뷰의 수퍼 또는 상위 뷰가 아닌 유닛이 적용된 변환 한 경우,이 크기

CGSizeMake(s.width*hypotf(tr.a, tr.b), s.height*hypotf(tr.c, tr.d)) 

그러나 :

+1

사과 문서에서 "프레임"에 대한 설명서는 다음과 같습니다. 경고 : transform 속성이 ID 변환이 아닌 경우이 속성의 값은 정의되지 않았으므로 무시해라. 그래서 변형이 적용될 때 프레임은 문제가되지 않습니다. "bounds"는 항상 원래 크기를 반환합니다 –

+0

실제로! 아,이 함수 라이브러리는 항상 잊어 버렸습니다. CGPathGetBoundingBox가 트릭이었습니다. 나는 작업 코드로 질문을 편집했다. 덕분에 많은 사람 –

+0

또한 센터 속성은 비정상 변환으로도 작동한다고 가정한다. – Olie

2

CGSizeApplyAffineTransform(size, transform)을 사용하면 변환 된 크기가 반환됩니다. CGPointCGRect 기능도 있습니다.

+0

CGSizeApplyAffineTransform에도 rotation이 포함되어 있으면 올바르게 작동하지 않지만 그렇지 않은 경우에는 크기 조정 만 적용되는 경우에 맞습니다. (내 실수로 내 질문에 회전 포함하지 않았다) –

2

간단한 : TR를 변환하는 (경계)의 크기 (S)와 볼이 적용되어 생성 된 크기를 갖는다 절대적인 측면에서 거의 의미가 없습니다.

임의의 변환이 뷰 또는 수퍼 뷰에 적용된 후 창 좌표에서 뷰의 절대 크기를 원하면 루트 변형까지 모든 뷰 변형을 구성하여 절대 변환 행렬을 먼저 계산해야합니다. 그 결과에 위 공식을 적용하십시오.

33

내가 사용

CGRect transformedBounds = CGRectApplyAffineTransform(view.bounds, view.transform); 
+0

나는 "view.bounds"가 더 나은 대답 일 것이라고 믿는다. 왜 프레임의 크기를 취하는 대신 경계를 변형시키는 거지? –

0

하지만 당신은 변환 회전 적용, 그것은 CGPathGetBoundingBox에 의해 적당한 크기를하지 않습니다.

2

이전 질문이지만 해결책을 찾고 많은 시도를 한 후에 여기에 부딪 혔습니다.그것은 간단했다.

view.layer.frame 모두 변환이 적용되었으며 크기는 view.layer.frame.size에서 쉽게 확인할 수 있습니다. 움직이지 않도록,

그리고 내 문제에 대한, 내 회전 뷰의 layer.anchorPoint을 변경 한 후 새 center 값을 계산하려고했다 -

- - 여기 아래는이 질문에 대한 답변하지 않습니다 . 그리고 마침내 이렇게했습니다. 마지막으로 역

CGPoint center = [self.superview convertPoint:CGPointMake(self.bounds.size.width/2, self.bounds.size.height/2) fromView:self]; 
self.layer.anchorPoint = CGPointMake(.5, .5); 
self.center = center; 

에 대한

CGPoint topLeft = [self.superview convertPoint:CGPointMake(0, 0) fromView:self]; 
self.layer.anchorPoint = CGPointMake(0, 0); 
self.center = topLeft; 

.

관련 문제