2010-01-22 13 views
10

Sto cercando di aggiungere immagini alle celle della tabella in un UITableView raggruppato ma gli angoli delle immagini non sono ritagliati. Qual è il modo migliore per ritagliare questi (oltre a ritagliarli in Photoshop? I contenuti della tabella sono dinamici.)Come aggiungere una UIImage a UITableViewCell raggruppato in modo da arrotondare gli angoli?

Ad esempio, la prima immagine in una tabella avrebbe bisogno solo dell'angolo in alto a sinistra arrotondato.

risposta

8

Questa era la mia soluzione, che potrebbe usare un po 'di refactoring:

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];  
} 

l'attuazione di tali funzioni, quindi controllare il indexPath nel metodo cellForRowAtIndexPath delegato per determinare quale angolo per arrotondare.

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

Grazie, Kevin. Ho rifattorizzato il codice in una categoria UIImage, quindi non devo copiare e incollare tutto ciò in ogni luogo. –

+2

Ottima risposta, grazie. Una correzione: imageMasked è trapelato. È necessario assegnare l'UIImage finale a una variabile, CGImageRelease (imageMasked) e quindi restituire UIImage. –

+0

.... UIImage * image = [UIImage imageWithCGImage: imageMasked]; CGImageRelease (imageMasked); immagine di ritorno; } Grazie. Questo era quello che stavo cercando. Adesso va bene. Grande. –

1

Non c'è un modo standard incorporato per farlo, ma non è terribilmente difficile da fare nel proprio codice. Esistono esempi su come arrotondare gli angoli di una UIImage sul Web, ad esempio http://blog.sallarp.com/iphone-uiimage-round-corners/.

+0

Huh.Speravo che ci sarebbe stato un modo standard più built-in come afferrare la maschera di forma della cella stessa. Ma sì - indovina no. –

0

C'è un modo integrato se si desidera visualizzare solo gli angoli arrotondati. Metti l'immagine in una UIImageView e poi imposta il cornerRadius del livello di UIImageView. Dovrai anche dire a UIImageView di agganciare i bordi ma questo ti darà angoli arrotondati.

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

OK, quindi ho commentato la soluzione di Kevin e ho provato questo. Per prima cosa, ho dovuto aggiungere il framework QuartzCore - setCornerRadius è in QuartzCore. Sfortunatamente, setCornerRadius arrotonda tutti e quattro gli angoli. Se voglio abbinare la forma di un UITableViewCell.imageView raggruppato, ho bisogno della parte superiore sinistra dell'immagine arrotondata sulla riga superiore - ma gli altri devono rimanere nitidi. Quindi, mentre setCornerRadius è conveniente, non è adatto per un'applicazione in cui è necessario selezionare e scegliere gli angoli da arrotondare. –

4

Se sei felice di avere tutti e quattro gli angoli arrotondati immagine, allora si può solo effettuare le seguenti operazioni durante la creazione della cellula:

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

Se anche voi volete inserto l'immagine dal confine , Ho descritto un simple category on UIImage to do it here.

+0

Assicurarsi di includere il framework QuartzCore e importare per utilizzare le proprietà del livello. – Ralphleon

+1

colpisce pesantemente le prestazioni –

1

Un paio le aggiunte/modifiche, spero che aiuta qualcuno:

1) roundtop e fondo tondo impl leggermente cambiata.

2) ha creato un metodo di classe in una classe separata, in modo che il riutilizzo sia più semplice, piuttosto che copiare/incollare ovunque.

In primo luogo, i nuovi dettagli di classe:

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

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

e la sua attuazione:

#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 

Per usare in un'altra classe (ad esempio, controller della vista):

#import "RoundedImages.h" 

.. .e successivamente lo usiamo in questo modo ...

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

Si noti che le "scelte" sopra erano solo un array mutabile che stavo usando su questa pagina che conteneva i dati per il tableview.

Devo aggiungere che lo snippet di utilizzo sopra riportato viene utilizzato all'interno del metodo cellForRowAtIndexPath e "cell" è uitableviewcell.

In ogni caso, funziona come un campione per me.

+0

Per favore [non usare firme o tagline] (http://stackoverflow.com/faq#signatures) nei tuoi messaggi – meagar

Problemi correlati