Me sorprendió no encontrar una respuesta a esta pregunta, tal vez es algo muy simple que de alguna manera pasar por alto :

Cómo obtener el tamaño real de un UIView después de aplicar un CGAffineTransform?

por ejemplo.

mi UIView tiene un tamaño de 300 x 200, puedo aplicar una escala de transformación digamos que el factor 2, tanto horizontal como vertical, por lo que el UIView ahora tiene 600 x 400 en la pantalla, pero es de los límites y la capa de límites todavía están volviendo un tamaño de 300 x 200 … donde puedo encontrar el tamaño real de la UIView ?

ps. olvidé mencionar también quiero girar el uiview. Si yo se aplican sólo a escala CGSizeApplyAffineTransform funciona bien, pero cuando también hay rotación, entonces no funciona correctamente.

Edición: drawnonward me señaló en la dirección correcta, acabo de refinado un poco el código para compilar y aquí está :

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 );

Ahora rect.tamaño contiene las dimensiones de la vista con la transformación aplicada
Gracias de nuevo a drawnonward

OriginalEl autor Marin Todorov | 2010-04-22

6 Comentarios

  1. 12

    [myView frame] devuelve el marco de la vista como se ve por el padre, para el diseño y tamaños relativos. [myView bounds] devuelve los límites de la vista como se ve por sí mismo, para el dibujo. Si usted tiene transformaciones aplicadas a múltiples puntos de vista, puede utilizar convertRect: a o desde un punto de vista.

    Edición:

    Tal vez algo como esto.

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

    El uso [view center] para encontrar la posición en el superview.

    Aquí está la documentación sobre el «marco» de la manzana docs: Advertencia: Si la transformación de la propiedad no es la identidad de transformación, el valor de esta propiedad es indefinido y por lo tanto debe ser ignorado. Así, el marco está fuera de toda duda cuando hay transformación aplicada. Y «límites» devuelve siempre el tamaño original
    De hecho! Argh, esta función las bibliotecas que yo siempre olvidan – CGPathGetBoundingBox era el truco. He editado la pregunta con el código de trabajo, muchas gracias hombre
    También tenga en cuenta que el centro de la propiedad se supone que funciona, incluso con los no-identidad se transforma.

    OriginalEl autor drawnonward

  2. 38

    Yo uso esta en C Objetivo:

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

    o en Swift 4:

    let transformedBounds = view.bounds.applying(view.transform)
    creo que «a la vista.de los límites» sería una mejor respuesta. ¿por qué están transformando los límites aquí en lugar de simplemente tomar el tamaño de la trama?

    OriginalEl autor Nikso

  3. 2

    Uso CGSizeApplyAffineTransform(size, transform) y devolverá una transformada de tamaño. Hay similares CGPoint y CGRect funciones.

    Que no funciona correctamente cuando CGSizeApplyAffineTransform incluye también la rotación, pero por lo demás está a la derecha en los casos no sólo la escala se aplica. (mi error yo no incluir también la rotación en mi pregunta)

    OriginalEl autor Ashley Clark

  4. 2

    Más simple: Una vista con (límites) de la talla s a la que transformar tr es aplicada tiene tamaño resultante:

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

    Sin embargo, si la vista superview o cualquier antepasado vista tiene cualquier no-unidad de transformar aplicada, de este tamaño, tiene poco sentido en términos absolutos.

    Si desea que el tamaño absoluto de una vista en la ventana de coordenadas después de cualquier transformación ha sido aplicada a la vista o sus superviews, usted debe primero calcular la absoluta transformación de la matriz mediante la composición de todos los de la vista de transformar a la raíz de la ventana y, a continuación, aplicar la fórmula anterior para el resultado.

    OriginalEl autor Marco B

  5. 2

    Vieja pregunta, pero se topó aquí, después de buscar una solución y un montón de intentos. Era simple;

    view.layer.frame tiene todas las transformaciones aplicadas y obtendrás el tamaño de view.layer.frame.size fácilmente.

    – por debajo de aquí no es una respuesta a esta pregunta – –

    Y para mi problema, yo estaba tratando de calcular nuevos center valor después de cambiar layer.anchorPoint de mi vista rotada, para que no se mueva. Y finalmente lo hizo así;

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

    para revertir

    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;

    finalmente.

    OriginalEl autor Furkan Mustafa

  6. 0

    Sino de aplicar una rotación de transformar, no consigue el tamaño adecuado por CGPathGetBoundingBox.

    OriginalEl autor applezqp

Dejar respuesta

Please enter your comment!
Please enter your name here