2010-01-22 7 views

Respuesta

8

Esta fue mi solución, que podría utilizar un poco de refactorización:

void addRoundedRectToPath(CGContextRef context, CGRect rect, float ovalWidth, float ovalHeight, BOOL top, BOOL bottom) 
{ 
    float fw, fh; 
    if (ovalWidth == 0 || ovalHeight == 0) { 
     CGContextAddRect(context, rect); 
     return; 
    } 
    CGContextSaveGState(context); 
    CGContextTranslateCTM (context, CGRectGetMinX(rect), CGRectGetMinY(rect)); 
    CGContextScaleCTM (context, ovalWidth, ovalHeight); 
    fw = CGRectGetWidth (rect)/ovalWidth; 
    fh = CGRectGetHeight (rect)/ovalHeight; 
    CGContextMoveToPoint(context, fw, fh/2); 
    CGContextAddArcToPoint(context, fw, fh, fw/2, fh, 0); 

    NSLog(@"bottom? %d", bottom); 

    if (top) { 
     CGContextAddArcToPoint(context, 0, fh, 0, fh/2, 3); 
    } else { 
     CGContextAddArcToPoint(context, 0, fh, 0, fh/2, 0); 
    } 

    if (bottom) { 
     CGContextAddArcToPoint(context, 0, 0, fw/2, 0, 3); 
    } else { 
     CGContextAddArcToPoint(context, 0, 0, fw/2, 0, 0); 
    } 

    CGContextAddArcToPoint(context, fw, 0, fw, fh/2, 0); 
    CGContextClosePath(context); 
    CGContextRestoreGState(context); 
} 

- (UIImage *)roundCornersOfImage:(UIImage *)source roundTop:(BOOL)top roundBottom:(BOOL)bottom { 
    int w = source.size.width; 
    int h = source.size.height; 

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 
    CGContextRef context = CGBitmapContextCreate(NULL, w, h, 8, 4 * w, colorSpace, kCGImageAlphaPremultipliedFirst); 

    CGContextBeginPath(context); 
    CGRect rect = CGRectMake(0, 0, w, h); 
    addRoundedRectToPath(context, rect, 4, 4, top, bottom); 
    CGContextClosePath(context); 
    CGContextClip(context); 

    CGContextDrawImage(context, CGRectMake(0, 0, w, h), source.CGImage); 

    CGImageRef imageMasked = CGBitmapContextCreateImage(context); 
    CGContextRelease(context); 
    CGColorSpaceRelease(colorSpace); 

    return [UIImage imageWithCGImage:imageMasked];  
} 

implementar esas funciones, a continuación, comprobar el indexPath en el método cellForRowAtIndexPath delegado para determinar qué esquina para redondear.

if (indexPath.row == 0) { 
      cell.imageView.image = [self roundCornersOfImage:coverImage roundTop:YES roundBottom:NO]; 
     } else if (indexPath.row == [indexPath length]) { 
      cell.imageView.image = [self roundCornersOfImage:coverImage roundTop:NO roundBottom:YES]; 
     } else { 
      cell.imageView.image = coverImage; 
     } 
+0

Gracias, Kevin. Refactoré el código en una categoría UIImage para que no tenga que copiar y pegar esto por todos lados. –

+2

Excelente respuesta, gracias. Una solución: imageMasked se está filtrando. Debe asignar el UIImage final a una variable, CGImageRelease (imageMasked) y luego devolver el UIImage. –

+0

.... UIImage * image = [UIImage imageWithCGImage: imageMasked]; CGImageRelease (imageMasked); imagen de retorno; } Gracias. Esto era lo que estaba buscando. Ahora está bien. Estupendo. –

1

no hay una construida en forma estándar de hacer esto, pero no es terriblemente difícil de hacer en su propio código. Hay ejemplos sobre cómo redondear esquinas en un UIImage en la web, ver por ejemplo http://blog.sallarp.com/iphone-uiimage-round-corners/.

+0

Huh.Esperaba que hubiera una forma estándar más integrada, como agarrar la máscara de forma de la celda. Pero sí, supongo que no. –

0

Hay una forma integrada si solo desea mostrar las esquinas redondeadas. Coloque la imagen en UIImageView y luego configure la esquinaRadius de la capa de UIImageView. También necesitarás decirle al UIImageView que recorte a los límites, pero eso te dará esquinas redondeadas.

UIImageView *myImageView = [[UIImageView alloc] initWithImage:...]; 
[myImageView setClipsToBounds:YES]; 
[[myImageView layer] setCornerRadius:5.0f]; 
+0

OK, así que comenté la solución de Kevin y probé esta. Primero, tuve que agregar el framework QuartzCore - setCornerRadius está en QuartzCore. Desafortunadamente, setCornerRadius redondea las cuatro esquinas. Si quiero hacer coincidir la forma de una UITableViewCell.imageView agrupada, necesito que la parte superior izquierda de la imagen esté redondeada en la fila superior, pero las demás deben mantenerse nítidas. Por lo tanto, aunque setCornerRadius es conveniente, no es adecuado para una aplicación en la que debe elegir las esquinas que desea redondear. –

4

Si estás contento de tener las cuatro esquinas redondeadas imagen, a continuación, puedes hacer lo siguiente al crear la célula:

cell.imageView.layer.masksToBounds = YES; 
cell.imageView.layer.cornerRadius = 10.0; 

Si también desea a la inserción de la imagen desde el límite , Describí un simple category on UIImage to do it here.

+0

Asegúrese de incluir el marco QuartzCore e importe para usar las propiedades de la capa. – Ralphleon

+1

hits en gran medida el rendimiento –

1

Un par adiciones/cambios, espero que ayude a alguien:

1) roundtop y fondo redondo impl cambiado ligeramente.

2) hizo un método de clase en clase aparte para reutilización es más fácil, en lugar de copiar/pegar en todas partes.

En primer lugar, los nuevos detalles de categoría:

#import <Foundation/Foundation.h> 
#import <QuartzCore/QuartzCore.h> 

@interface RoundedImages : NSObject { 
} 
+(UIImage *)roundCornersOfImage:(UIImage *)source roundTop:(BOOL)top roundBottom:(BOOL)bottom; 
@end 

y su aplicación:

#import "RoundedImages.h" 

@implementation RoundedImages 

void addRoundedRectToPath(CGContextRef context, CGRect rect, float ovalWidth, float ovalHeight, BOOL top, BOOL bottom) 
{ 
    float fw, fh; 
    if (ovalWidth == 0 || ovalHeight == 0) { 
     CGContextAddRect(context, rect); 
     return; 
    } 
    CGContextSaveGState(context); 
    CGContextTranslateCTM (context, CGRectGetMinX(rect), CGRectGetMinY(rect)); 
    CGContextScaleCTM (context, ovalWidth, ovalHeight); 
    fw = CGRectGetWidth (rect)/ovalWidth; 
    fh = CGRectGetHeight (rect)/ovalHeight; 
    CGContextMoveToPoint(context, fw, fh/2); 

    if (top) { 
     CGContextAddArcToPoint(context, fw, fh, fw/2, fh, 3); 
     CGContextAddArcToPoint(context, 0, fh, 0, fh/2, 3); 
     CGContextAddArcToPoint(context, 0, 0, fw/2, 0, 0); 
     CGContextAddArcToPoint(context, fw, 0, fw, fh/2, 0); 
    } else { 
     CGContextAddArcToPoint(context, fw, fh, fw/2, fh, 0); 
     CGContextAddArcToPoint(context, 0, fh, 0, fh/2, 0); 
     CGContextAddArcToPoint(context, 0, 0, fw/2, 0, 3); 
     CGContextAddArcToPoint(context, fw, 0, fw, fh/2, 3); 
    } 

    CGContextClosePath(context); 
    CGContextRestoreGState(context); 
} 

+(UIImage *)roundCornersOfImage:(UIImage *)source roundTop:(BOOL)top roundBottom:(BOOL)bottom { 
    int w = source.size.width; 
    int h = source.size.height; 

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 
    CGContextRef context = CGBitmapContextCreate(NULL, w, h, 8, 4 * w, colorSpace, kCGImageAlphaPremultipliedFirst); 

    CGContextBeginPath(context); 
    CGRect rect = CGRectMake(0, 0, w, h); 
    //addRoundedRectToPath(context, rect, 4, 4, top, bottom); 
    addRoundedRectToPath(context, rect, 5, 5, top, bottom); 
    CGContextClosePath(context); 
    CGContextClip(context); 

    CGContextDrawImage(context, CGRectMake(0, 0, w, h), source.CGImage); 

    CGImageRef imageMasked = CGBitmapContextCreateImage(context); 
    CGContextRelease(context); 
    CGColorSpaceRelease(colorSpace); 

    //return [UIImage imageWithCGImage:imageMasked]; 
    UIImage *image = [UIImage imageWithCGImage:imageMasked]; 
    CGImageRelease(imageMasked); 
    return image; 
} 

@end 

Para usar en otra clase (por ejemplo, controlador de vista):

#import "RoundedImages.h" 

.. .y luego lo usamos como esto ...

UIImageView *imageView = nil; 
    UIImage *img = [UIImage imageNamed:@"panel.png"]; 

    if (indexPath.row == 0) { 
     imageView = [[UIImageView alloc]initWithImage:[RoundedImages roundCornersOfImage:img roundTop:YES roundBottom:NO]]; 
    } 
    else if (indexPath.row == ([choices count]-1)) 
    { 
     imageView = [[UIImageView alloc]initWithImage:[RoundedImages roundCornersOfImage:img roundTop:NO roundBottom:YES]]; 
    } 
    else { 
     imageView = [[UIImageView alloc]initWithImage:img]; 
    } 
    cell.backgroundColor = [UIColor clearColor]; 
    imageView.clipsToBounds = NO; 
    cell.backgroundView = imageView; 
    cell.backgroundView = [[UIView alloc] initWithFrame:CGRectZero]; 
    [cell.backgroundView addSubview:imageView]; 
    [imageView release]; 

Tenga en cuenta que las "decisiones" de arriba fue simplemente una matriz mutable que estaba usando en esta página que contiene los datos de la tableview.

debo añadir que el fragmento de uso por encima se utiliza dentro de su método cellForRowAtIndexPath, y "célula" es una UITableViewCell.

De todos modos, funciona como un campeón para mí.

+0

Por favor [no use firmas o eslóganes] (http://stackoverflow.com/faq#signatures) en sus publicaciones – meagar

Cuestiones relacionadas