Получите размер UIView после применения CGAffineTransform
Я был удивлен, что не нашел ответа на этот вопрос, может быть, это очень просто, я почему-то не замечаю:
Как получить реальный размер UIView после применения к нему CGAffineTransform?
например.
мой UIView имеет размер 300 x 200, я применяю масштабирующее преобразование, пусть говорят коэффициент 2 как по горизонтали, так и по вертикали, поэтому UIView теперь принимает 600 x 400 на экране, но он ограничивается, и его границы слоя все еще возвращают размер 300 x 200... где я могу найти реальный размер UIView?
пс. забыл упомянуть, что хочу также повернуть uiview. Если я применяю только масштабирование, CGSizeApplyAffineTransform отлично работает, но когда есть и вращение, то оно не работает должным образом.
Edit: drawonward указал мне в правильном направлении, я немного уточнил код для компиляции, и вот он:
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 содержит размеры представления с примененным преобразованием
Еще раз спасибо обратившемуся
Ответы
Ответ 1
[myView frame]
возвращает кадр представления, как видно родительскому, для макета и относительных размеров. [myView bounds]
возвращает границы вида, как показано самим собой, для рисования. Если у вас есть преобразования, применяемые к нескольким представлениям, вы можете использовать convertRect:
для или из представления.
Edit:
Может быть, что-то вроде этого.
CGRect rect = [view bounds];
CGPathRef path = CGPathCreateMutable();
rect.origin = CGPointZero;
CGPathAddRect( rect , [view transform] );
rect = CGPathGetBoundingBox( path );
CGPathRelease( path );
Использование [view center]
для поиска позиции в супервизии.
Ответ 2
Я использую:
CGRect transformedBounds = CGRectApplyAffineTransform(view.bounds, view.transform);
Ответ 3
Используйте CGSizeApplyAffineTransform(size, transform)
, и он вернет преобразованный размер. Существуют аналогичные функции CGPoint
и CGRect
.
Ответ 4
Упрощение: представление с (границами) размера s, к которому применяется преобразование tr, имеет результирующий размер:
CGSizeMake(s.width*hypotf(tr.a, tr.b), s.height*hypotf(tr.c, tr.d))
Однако, если view viewview или любой вид предка имеют какое-либо не-единичное преобразование, этот размер практически не имеет смысла в абсолютных терминах.
Если вы хотите, чтобы абсолютный размер представления в координатах окна после любого произвольного преобразования был применен к этому представлению или его супервизорам, вы должны сначала вычислить матрицу абсолютного преобразования, составив все преобразование вида до корневого окна, и затем примените приведенную выше формулу к результату.
Ответ 5
Старый вопрос, но наткнулся на это, после поиска решения и тонны попыток. Это было просто:
view.layer.frame
имеет все преобразования, и вы легко получите размер от view.layer.frame.size
.
- ниже здесь нет ответа на этот вопрос -
И для моей проблемы я пытался вычислить новое значение center
после изменения layer.anchorPoint
моего повернутого представления, поэтому он не перемещается. И, наконец, сделал это так:
CGPoint topLeft = [self.superview convertPoint:CGPointMake(0, 0) fromView:self];
self.layer.anchorPoint = CGPointMake(0, 0);
self.center = topLeft;
для обратного
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;
в конце концов.
Ответ 6
Но вы применяете вращающееся преобразование, оно не получает правильный размер CGPathGetBoundingBox.