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

Внутренняя тень в UILabel

Можно ли создать такой UILabel с внутренней и внешней тенью?

alt text http://dl.getdropbox.com/u/80699/Bildschirmfoto%202010-07-12%20um%2021.28.57.png

Я знаю только shadowColor и shadowOffset

масштаб изображения:

alt text http://dl.getdropbox.com/u/80699/Bildschirmfoto%202010-07-12%20um%2021.39.56.png

спасибо!

4b9b3361

Ответ 1

Ответ dmaclach подходит только для форм, которые можно легко инвертировать. Мое решение - это настраиваемое представление, которое работает с любой формой, а также с текстом. Он требует iOS 4 и независим от разрешения.

Во-первых, графическое объяснение того, что делает код. Форма здесь - это круг. alt text

Код рисует текст с белой меткой. Если это не требуется, код может быть реорганизован дальше, потому что dropshadow нужно замаскировать по-разному. Если вам это нужно в более ранней версии iOS, вам придется заменить блок и использовать (раздражающий) CGBitmapContext.

- (UIImage*)blackSquareOfSize:(CGSize)size {
  UIGraphicsBeginImageContextWithOptions(size, NO, 0);  
  [[UIColor blackColor] setFill];
  CGContextFillRect(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, size.width, size.height));
  UIImage *blackSquare = UIGraphicsGetImageFromCurrentImageContext();
  UIGraphicsEndImageContext();
  return blackSquare;
}


- (CGImageRef)createMaskWithSize:(CGSize)size shape:(void (^)(void))block {
  UIGraphicsBeginImageContextWithOptions(size, NO, 0);  
  block();
  CGImageRef shape = [UIGraphicsGetImageFromCurrentImageContext() CGImage];
  UIGraphicsEndImageContext();  
    CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(shape),
                                      CGImageGetHeight(shape),
                                      CGImageGetBitsPerComponent(shape),
                                      CGImageGetBitsPerPixel(shape),
                                      CGImageGetBytesPerRow(shape),
                                      CGImageGetDataProvider(shape), NULL, false);
  return mask;
}


- (void)drawRect:(CGRect)rect {
  UIFont *font = [UIFont fontWithName:@"HelveticaNeue-Bold" size:40.0f];
  CGSize fontSize = [text_ sizeWithFont:font];

  CGImageRef mask = [self createMaskWithSize:rect.size shape:^{
    [[UIColor blackColor] setFill];
    CGContextFillRect(UIGraphicsGetCurrentContext(), rect);
    [[UIColor whiteColor] setFill];
    // custom shape goes here
    [text_ drawAtPoint:CGPointMake((self.bounds.size.width/2)-(fontSize.width/2), 0) withFont:font];
    [text_ drawAtPoint:CGPointMake((self.bounds.size.width/2)-(fontSize.width/2), -1) withFont:font];
  }];

  CGImageRef cutoutRef = CGImageCreateWithMask([self blackSquareOfSize:rect.size].CGImage, mask);
  CGImageRelease(mask);
  UIImage *cutout = [UIImage imageWithCGImage:cutoutRef scale:[[UIScreen mainScreen] scale] orientation:UIImageOrientationUp];
  CGImageRelease(cutoutRef);  

  CGImageRef shadedMask = [self createMaskWithSize:rect.size shape:^{
    [[UIColor whiteColor] setFill];
    CGContextFillRect(UIGraphicsGetCurrentContext(), rect);
    CGContextSetShadowWithColor(UIGraphicsGetCurrentContext(), CGSizeMake(0, 1), 1.0f, [[UIColor colorWithWhite:0.0 alpha:0.5] CGColor]);
    [cutout drawAtPoint:CGPointZero];
  }];

  // create negative image
  UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0);
  [[UIColor blackColor] setFill];
  // custom shape goes here
  [text_ drawAtPoint:CGPointMake((self.bounds.size.width/2)-(fontSize.width/2), -1) withFont:font];
  UIImage *negative = UIGraphicsGetImageFromCurrentImageContext();
  UIGraphicsEndImageContext(); 

  CGImageRef innerShadowRef = CGImageCreateWithMask(negative.CGImage, shadedMask);
  CGImageRelease(shadedMask);
  UIImage *innerShadow = [UIImage imageWithCGImage:innerShadowRef scale:[[UIScreen mainScreen] scale] orientation:UIImageOrientationUp];
  CGImageRelease(innerShadowRef);

  // draw actual image
  [[UIColor whiteColor] setFill];
  [text_ drawAtPoint:CGPointMake((self.bounds.size.width/2)-(fontSize.width/2), -0.5) withFont:font];
  [[UIColor colorWithWhite:0.76 alpha:1.0] setFill];
  [text_ drawAtPoint:CGPointMake((self.bounds.size.width/2)-(fontSize.width/2), -1) withFont:font];  

  // finally apply shadow
  [innerShadow drawAtPoint:CGPointZero];
}

Ответ 2

Хотя ответ Стива работает, он не масштабируется для моего конкретного случая, и поэтому я создал внутреннюю тень, применив тень к CGPath после отсечения моего контекста:

CGContextRef context = UIGraphicsGetCurrentContext();

// clip context so shadow only shows on the inside
CGPathRef roundedRect = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:4].CGPath;
CGContextAddPath(context, roundedRect);
CGContextClip(context);

CGContextAddPath(context, roundedRect);
CGContextSetShadowWithColor(UIGraphicsGetCurrentContext(), CGSizeMake(0, 0), 3, [UIColor colorWithWhite:0 alpha:1].CGColor);
CGContextSetStrokeColorWithColor(context, [UIColor colorWithWhite:0 alpha:1].CGColor);
CGContextStrokePath(context);

Результат:

enter image description here

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

Ответ 4

Да, у меня есть сообщение в блоге об этом здесь. Короткий ответ заключается в том, чтобы заимствовать JTAInnerShadowLayer из здесь, подкласса UILabel и изменить его laylasslass, переопределив + (Class)layerClass, чтобы он возвращал класс JTAInnerShadowLayer, подобный этому

+ (Class)layerClass
{
  return [JTAInnerShadowLayer class];
}

Затем в методе init для слоя создайте JTAInnerShadowLayer примерно так:

[self setBackgroundColor:[UIColor clearColor]];
JTAInnerShadowLayer *innerShadow = (JTAInnerShadowLayer *)[self layer];
[innerShadow setClipForAnyAlpha:YES];
[innerShadow setOutsideShadowSize:CGSizeMake(0.0, 1.0) radius:1.0];
[innerShadow setInsideShadowSize:CGSizeMake (0.0, 4.0) radius:6.0];
/* Uncomment this to make the label also draw the text (won't work well
   with black text!*/
//[innerShadow drawOriginalImage];

(или просто заимствовать класс JTAIndentLabel).

Ответ 5

Вам нужно будет сделать свой собственный рисунок, чтобы получить внутреннюю тень. В настоящее время нет способа сделать это со стандартным UILabel.

Вот разумное объяснение о внутренней тени с кварцем.

Внутренняя тень в основной графике

Ответ 6

Попробуйте PaintCode пробную версию! Для новичков вы узнаете, как создавать собственные рисунки. Это очень приятно!: 3 Вы можете использовать его для практики или для обучения, но не используйте его все время, вы также должны узнать, как создавать чертежи самостоятельно.

Отказ от ответственности: я не индоссант, меня просто поразило мое открытие.;)