Как добавить UIImage в сгруппированный UITableViewCell, чтобы он закруглял углы? - PullRequest
10 голосов
/ 22 января 2010

Я пытаюсь добавить изображения в ячейки таблицы в сгруппированном UITableView, но углы изображений не обрезаны. Как лучше всего их обрезать (кроме как обрезать их в Photoshop? Содержимое таблицы динамическое).

Например, первое изображение в таблице будет нуждаться только в закругленном верхнем левом углу.

Ответы [ 5 ]

8 голосов
/ 22 января 2010

Это было мое решение, которое могло бы использовать небольшой рефакторинг:

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

Реализуйте эти функции, затем проверьте indexPath в методе делегата cellForRowAtIndexPath, чтобы определить, какой угол округлять.

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;
        }
4 голосов
/ 15 марта 2010

Если вы счастливы, что все четыре угла изображения округлены, то при создании ячейки вы можете просто сделать следующее:

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

Если вы также хотите вставить изображение с границы, я описал простую категорию в UIImage, чтобы сделать это здесь .

1 голос
/ 08 декабря 2010

Пара дополнений / изменений, надеюсь, кому-то это поможет:

1) Значения атрибутов roundTop и roundBottom немного изменены.

2) создал метод класса в отдельном классе, так что повторное использование проще, чем везде копирование / вставка.

Во-первых, новые детали класса:

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

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

И его реализация:

#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

Для использования в другом классе (например, просмотр контроллера):

#import "RoundedImages.h"

... и позже мы используем это так ...

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

Обратите внимание, что приведенные выше "варианты выбора" были просто изменяемым массивом, который я использовал на этой странице и содержал данные для просмотра таблицы.

Я должен добавить, что приведенный выше фрагмент использования используется внутри вашего метода cellForRowAtIndexPath, а "cell" - это элемент uitableviewcell.

Во всяком случае, работает как чемпион для меня.

1 голос
/ 22 января 2010

Нет встроенного стандартного способа сделать это, но это не очень сложно сделать в вашем собственном коде. Есть примеры того, как округлять углы на UIImage в сети, см., Например, http://blog.sallarp.com/iphone-uiimage-round-corners/.

0 голосов
/ 23 января 2010

Есть встроенный способ, если вы хотите просто отобразить закругленные углы.Поместите изображение в UIImageView и затем установите cornerRadius слоя UIImageView.Вам также нужно будет указать UIImageView обрезать границы, но это даст вам закругленные углы.

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