Подтвердить что ты не робот

IOS - Как добиться эффекта тиснения для текста на UILabel?

enter image description here

Могу ли я узнать, как использовать эффект тиснения как текст " Напоминания", как показано на картинке?

Похоже, что текст встроен?

Спасибо

4b9b3361

Ответ 1

ОБНОВЛЕНИЕ ДЛЯ iOS 7.0

В iOS 7.0 Apple добавила новый атрибут NSTextEffectAttributeName для атрибутированных строк. Если целью развертывания является iOS 7.0 или новее, вы можете установить этот атрибут в NSTextEffectLetterpressStyle для рисования атрибутной строки в тисненном стиле.

ОРИГИНАЛ

Я не могу точно сказать, как Apple рисует тисненый текст. Мне кажется, что они заполняют глифы строки красноватым цветом, затем применяют тень вокруг внутренних краев глифов, а также применяют очень слабую тень вдоль верхних внешних границ глифов. Я попробовал это и вот как это выглядит:

iPhone simulator screen shot

В верхней части мой рендеринг. Ниже это простой UILabel с тенью, как предложил Крис в своем ответе. Я помещал снимок экрана приложения напоминаний в фоновом режиме.

Вот мой код.

Сначала вам нужна функция, которая создает маску изображения вашей строки. Вы будете использовать маску для рисования самой строки, а затем для рисования тени, которая появляется только внутри внутренних границ строки. Это изображение имеет только альфа-канал и RGB-каналы.

- (UIImage *)maskWithString:(NSString *)string font:(UIFont *)font size:(CGSize)size
{
    CGRect rect = { CGPointZero, size };
    CGFloat scale = [UIScreen mainScreen].scale;
    CGColorSpaceRef grayscale = CGColorSpaceCreateDeviceGray();
    CGContextRef gc = CGBitmapContextCreate(NULL, size.width * scale, size.height * scale, 8, size.width * scale, grayscale, kCGImageAlphaOnly);
    CGContextScaleCTM(gc, scale, scale);
    CGColorSpaceRelease(grayscale);
    UIGraphicsPushContext(gc); {
        [[UIColor whiteColor] setFill];
        [string drawInRect:rect withFont:font];
    } UIGraphicsPopContext();

    CGImageRef cgImage = CGBitmapContextCreateImage(gc);
    CGContextRelease(gc);
    UIImage *image = [UIImage imageWithCGImage:cgImage scale:scale orientation:UIImageOrientationDownMirrored];
    CGImageRelease(cgImage);

    return image;
}

Во-вторых, вам нужна функция, которая инвертирует эту маску. Вы будете использовать это, чтобы заставить CoreGraphics нарисовать тень вокруг внутренних границ строки. Это должно быть полное изображение RGBA. (iOS, похоже, не поддерживает оттенки серого + альфа-изображения.)

- (UIImage *)invertedMaskWithMask:(UIImage *)mask
{
    CGRect rect = { CGPointZero, mask.size };
    UIGraphicsBeginImageContextWithOptions(rect.size, NO, mask.scale); {
        [[UIColor blackColor] setFill];
        UIRectFill(rect);
        CGContextClipToMask(UIGraphicsGetCurrentContext(), rect, mask.CGImage);
        CGContextClearRect(UIGraphicsGetCurrentContext(), rect);
    }
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return image;
}

Вы можете использовать их в функции, которая рисует красную строку и применяет тень к ее внутренним краям.

-(UIImage *)imageWithInteriorShadowAndString:(NSString *)string font:(UIFont *)font textColor:(UIColor *)textColor size:(CGSize)size
{
    CGRect rect = { CGPointZero, size };
    UIImage *mask = [self maskWithString:string font:font size:rect.size];
    UIImage *invertedMask = [self invertedMaskWithMask:mask];
    UIImage *image;
    UIGraphicsBeginImageContextWithOptions(rect.size, NO, [UIScreen mainScreen].scale); {
        CGContextRef gc = UIGraphicsGetCurrentContext();
        // Clip to the mask that only allows drawing inside the string image.
        CGContextClipToMask(gc, rect, mask.CGImage);
        // We apply the mask twice because we're going to draw through it twice.
        // Only applying it once would make the edges too sharp.
        CGContextClipToMask(gc, rect, mask.CGImage);
        mask = nil; // done with mask; let ARC free it

        // Draw the red text.
        [textColor setFill];
        CGContextFillRect(gc, rect);

        // Draw the interior shadow.
        CGContextSetShadowWithColor(gc, CGSizeZero, 1.6, [UIColor colorWithWhite:.3 alpha:1].CGColor);
        [invertedMask drawAtPoint:CGPointZero];
        invertedMask = nil; // done with invertedMask; let ARC free it

        image = UIGraphicsGetImageFromCurrentImageContext();
    }
    UIGraphicsEndImageContext();
    return image;
}

Затем вам понадобится функция, которая принимает изображение и возвращает копию со слабой восходящей тенью.

- (UIImage *)imageWithUpwardShadowAndImage:(UIImage *)image
{
    UIGraphicsBeginImageContextWithOptions(image.size, NO, image.scale); {
        CGContextSetShadowWithColor(UIGraphicsGetCurrentContext(), CGSizeMake(0, -1), 1, [UIColor colorWithWhite:0 alpha:.15].CGColor);
        [image drawAtPoint:CGPointZero];
    }
    UIImage *resultImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return resultImage;
}

Наконец, вы можете объединить эти функции для создания рельефного изображения вашей строки. Я положил свое окончательное изображение в UIImageView для легкого тестирования.

- (void)viewDidLoad
{
    [super viewDidLoad];

    CGRect rect = self.imageView.bounds;
    NSString *string = @"Reminders";
    UIFont *font = [UIFont systemFontOfSize:33];
    UIImage *interiorShadowImage = [self imageWithInteriorShadowAndString:string
        font:font
        textColor:[UIColor colorWithHue:0 saturation:.9 brightness:.7 alpha:1]
        size:rect.size];
    UIImage *finalImage = [self imageWithUpwardShadowAndImage:interiorShadowImage];

    self.imageView.image = finalImage;
}

Ответ 2

Это выглядит как тень вокруг текста. Вы устанавливаете его в IB в той же области, где вы устанавливаете цвет текста - выберите подходящий цвет для тени и задайте, как вам нужно смещение тени (в примере, который вы разместили, похоже, что они задают цвет тени тем же цветом как текст и смещение 0 горизонтальной и -1 вертикальной (что означает один пиксель вверх).

В коде свойства задаются следующим образом (если вы уже настроили UILabel с именем, соответственно, "label":

label.shadowColor = [UIColor blackColor]; // Choose your color here - in the example
                                          // posted, they probably chose a similar color
                                          // to the text color and then set the alpha
                                          // down around 0.7 or so so the shadow would be
                                          // faint.
label.shadowOffset = CGSizeMake(0,-1);    // First parameter is horizontal, second is vertical

Ответ 3

Вы можете настроить свой эффект на основе этого примера enter image description here