Tengo un UIView objeto que gira mediante CALayer‘s transformar:

//Create uiview object.
UIImageView *block = [[UIImageView alloc] initWithFrame....]

//Apply rotation.
CATransform3D basicTrans = CATransform3DIdentity;
basicTrans.m34 = 1.0/-distance;
blockImage.layer.transform = CATransform3DRotate(basicTrans, rangle, 1.0f, 0.0f, 0.0f);

Después de rotar los bordes del objeto no son de suavizado de líneas. Necesito de suavizado de ellos.
Ayúdame, por favor. ¿Cómo se puede hacer?

InformationsquelleAutor Oleg | 2011-11-29

4 Comentarios

  1. 43

    Una forma de hacer esto es mediante la colocación de la imagen dentro de otro punto de vista que es de 5 píxeles más grandes. La más grande vista deben tener un transparente rasterizado frontera que suavizar los bordes de la UIImageView:

    view.layer.borderWidth = 3; 
    view.layer.borderColor = [UIColor clearColor].CGColor; 
    view.layer.shouldRasterize = YES; 
    view.layer.rasterizationScale = [[UIScreen mainScreen] scale];

    A continuación, coloque su UIImageView dentro de este padre de la vista y del centro (Con 2.5 píxeles alrededor de cada borde).

    Por último, gire la vista principal en lugar de la vista de la imagen.

    Funciona muy bien también puede encapsular toda la cosa en la clase que crea la jerarquía.

    • Puede que desee agregar view.layer.rasterizationScale = [[UIScreen mainScreen] scale]; para evitar borrosa en pantallas Retina.
    • Este comentario debe ser parte de la respuesta. La configuración de ‘shouldRasterize» la propiedad no es suficiente!
    • Estás en lo correcto. Hecho.
    • tounaobun la respuesta de un mejor desempeño. Comprobar mi comentario más abajo.
  2. 37

    Simplemente agregar este par clave-valor a su Info.plist: UIViewEdgeAntialiasing conjunto para YES.

    • Este es el asesino!
    • fantástico! Cualquier idea de que el impacto en el rendimiento?
    • Viene con penalización de rendimiento, evitar que si se puede.
    • Perfecto y más fácil solución.
  3. 25

    de verificación allowsEdgeAntialiasing propiedad de CALayer.

    block.layer.allowsEdgeAntialiasing = YES; //iOS7 and above.
    • como antes (Info.plist), pero un control más granular! Excelente!
    • El aceptó responder funciona igual que este, pero este tiene un mejor rendimiento. Los dos pasan la misma RAM, pero esta solución ofrece más FPS para el usuario.
    • La documentación para esta propiedad dice que el valor es NO, si la Info.plist valor está ausente. Al parecer, usted no puede simplemente, sólo esta propiedad, pero se han de usar en combinación con el plist. No lo he probado ¿qué sucede si no se establece la propiedad, pero a juzgar por la respuesta de la AddisDev, el valor predeterminado es sí en ese caso. Así que si hay un impacto en el rendimiento y no necesita de suavizado de líneas, parece que la cosa a hacer es establecer este valor a NINGUNA.
  4. 3

    Yo tenía un problema similar al rotar alrededor del eje z. Configuración de shouldRasterize = SÍ impidió que los bordes dentados sin embargo, se llegó a un costo de rendimiento. En mi caso me fue re-uso de las vistas (y sus capas) y mantener la shouldRasterize = SÍ fue frenar las cosas.

    La solución fue, para apagar la rasterización justo después de que yo no la necesito. Sin embargo, ya que la animación se ejecuta en otro hilo, no había manera de saber cuando la animación se completa…hasta que me enteré de un extremadamente útil CATransaction método. Este es un código que he utilizado y debe ilustrar su uso:

    //Create a key frame animation
    CAKeyframeAnimation *wiggle = [CAKeyframeAnimation animationWithKeyPath:@"transform"];
    NSInteger frequency = 5; //Higher value for faster vibration
    NSInteger amplitude = 25; //Higher value for lower amplitude
    //Create the values it will pass through    
    NSMutableArray *valuesArray = [[NSMutableArray alloc] init];
    NSInteger direction = 1;
    
    [valuesArray addObject:@0.0];
    
    for (NSInteger i = frequency; i > 0; i--, direction *= -1) {
        [valuesArray addObject:@((direction * M_PI_4 * (CGFloat)i / (CGFloat)amplitude))];
    }
    
    [valuesArray addObject:@0.0];
    [wiggle setValues:valuesArray];
    
    //Set the duration
    [wiggle setAdditive:YES];
    [wiggle setValueFunction:[CAValueFunction functionWithName:kCAValueFunctionRotateZ]];
    [wiggle setDuration:0.6];
    
    //Turn on rasterization to prevent jagged edges (anti-aliasing issues)
    viewToRotate.layer.shouldRasterize = YES;
    
    //************ Important step **************
    //Very usefull method. Block returns after ALL animations have completed.
    [CATransaction setCompletionBlock:^{
        viewToRotate.layer.shouldRasterize = NO;
    }];
    //Animate the layer
    [viewToRotate.layer addAnimation:wiggle forKey:@"wiggleAnimation"];

    trabajó como un encanto para mí.

    No he intentado usar esta implícito con animaciones (es decir, las animaciones que suceder debido a un cambio de valor en la animación de la propiedad de un no-vista asociada a la capa), sin embargo espero que funcione tan largo como el CATransaction método es llamado antes de que el cambio de propiedad, como garantía de que el bloque se da a CATransaction antes de que una animación se inicia.

Dejar respuesta

Please enter your comment!
Please enter your name here