代码之家  ›  专栏  ›  技术社区  ›  choise

uilabel中的内部阴影

  •  18
  • choise  · 技术社区  · 14 年前

    有没有可能用内部和外部阴影创建这样一个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

    谢谢!

    6 回复  |  直到 10 年前
        1
  •  126
  •   Steven XM    14 年前

    dmaclach的答案只适用于容易反转的形状。我的解决方案是一个自定义视图,可以处理任何形状和文本。它需要iOS 4,并且与分辨率无关。

    首先,对代码的作用进行图形解释。这里的形状是一个圆。

    代码用白色阴影绘制文本。如果不需要,可以进一步重构代码,因为Dropshadow需要以不同的方式进行屏蔽。如果在旧版本的iOS上需要它,则必须替换块并使用(恼人的)cgBitmapContext。

    —(uiimage*)blackquareofsize:(cgsize)大小{
    uigraphicsbeginimagecontextwithoptions(大小,否,0);
    [[uicolor blackcolor]setfill];
    cContextFillRect(uigraphicsgetCurrentContext(),cDirectMake(0,0,size.width,size.height));
    uiimage*blacksquare=uigraphicsGetImageFromCurrentImageContext();
    uigraphicsEndImageContext();
    返回黑方;
    }
    
    
    -(cgImageRef)CreateMaskWithSize:(cgSize)大小形状:(void(^)(void))块{
    uigraphicsbeginimagecontextwithoptions(大小,否,0);
    块();
    cgimageref shape=[uigraphicsGetImageFromCurrentImageContext()cgimage];
    uigraphicsEndImageContext();
    cgImageRef Mask=cgImageMaskCreate(cgImageGetWidth(shape)),
    CGImageGetHeight(形状),
    CGImageGetBitsPerComponent(形状),
    CGImageGetBitsPerPixel(形状),
    CGImageGetBytesPerow(形状),
    cImageGetDataProvider(shape),空,假);
    返回掩模;
    }
    
    
    -(无效)drawrect:(cgrect)rect{
    uiFONT*FONT=[uiFONT FONTWITHNAME:@“Helveticaneue-bold”尺寸:40.0F];
    cgsize fontsize=[文本大小带字体:字体];
    
    cgimageref mask=[自我创建的maskwithsize:rect.size形状:]^{
    [[uicolor blackcolor]setfill];
    cContextFillRect(uigraphicsgetCurrentContext(),rect);
    [[uicolor whitecolor]setfill];
    //此处显示自定义形状
    [文本绘制点:cgpointmake((self.bounds.size.width/2)-(font size.width/2),0),字体:字体];
    [文本绘制点:cgpointmake((self.bounds.size.width/2)-(font size.width/2),-1)带字体:字体];
    };
    
    cImageRef CutoureRef=cImageCreateWithMask([Self BlackQuareOfSize:rect.size].cImage,Mask);
    CGIMAGERELEASE(掩模);
    uiimage*cutout=[uiimage imagewithcgimage:cututoref scale:[uiscreen mainscreen]scale]方向:uiimageoritionup];
    CGIMAGERELEASE(剪切参考);
    
    CGIMAGEREF SHADEDMASK=[自我创建掩码WITHSIZE:rect.SIZE形状:]^{
    [[uicolor whitecolor]setfill];
    cContextFillRect(uigraphicsgetCurrentContext(),rect);
    cgContextSetsHadowWithColor(uigraphicsGetCurrentContext(),cgSizemake(0,1),1.0f,[[uicolor colorWithWhite:0.0 alpha:0.5]cgColor]);
    [剪切绘图点:cgpointzero];
    };
    
    //创建负像
    uigraphicsbeginimagecontextwithoptions(rect.size,no,0);
    [[uicolor blackcolor]setfill];
    //此处显示自定义形状
    [文本绘制点:cgpointmake((self.bounds.size.width/2)-(font size.width/2),-1)带字体:字体];
    uiimage*负=uigraphicsGetImageFromCurrentImageContext();
    uigraphicsEndImageContext();
    
    cImageRef innershadowRef=cImageCreateWithMask(negative.cgImage,shaddedmask);
    CGIMAGERELEASE(阴影任务);
    uiimage*innershadow=[uiimage imagewithcgimage:innershadowref scale:[uiscreen mainscreen]scale]方向:uiimageoritionup];
    CGIMAGERELEASE(InnershadowRef);
    
    //绘制实际图像
    [[uicolor whitecolor]setfill];
    [文本绘制点:cgpointmake((self.bounds.size.width/2)-(font size.width/2),-0.5),字体:字体];
    [uicolor colorwithwhite:0.76 alpha:1.0]setfill];
    [文本绘制点:cgpointmake((self.bounds.size.width/2)-(font size.width/2),-1)带字体:字体];
    
    //最后应用阴影
    [innershadow drawAtpoint:cgpointzero];
    }
    < /代码> 
    很容易倒转。我的解决方案是一个自定义视图,可以处理任何形状和文本。它需要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
  •  13
  •   samvermette    13 年前

    虽然史蒂夫的回答确实有效,但它并没有按我的具体情况进行缩放,因此我在剪切上下文后,通过将阴影应用到cgpath,最终创建了一个内部阴影:

    cgContextRef context=uigraphicsGetCurrentContext();
    
    //剪辑上下文,使阴影仅显示在内部
    cgpathref roundedrect=[uibezierpath bezierpathwithroundedrect:rect cornerradius:4].cgpath;
    cContextAddPath(上下文,RoundedRect);
    cContextClip(上下文);
    
    cContextAddPath(上下文,RoundedRect);
    cgContextSetsHadowWithColor(uigraphicsGetCurrentContext(),cgSizemake(0,0),3,[uicolor colorWithWhite:0 alpha:1].cgColor);
    cgContextSetStrokeColorWithColor(上下文,[uicolor colorWithWhite:0 alpha:1].cgColor);
    cContextStrokePath(上下文);
    < /代码> 
    
    

    结果是:

    可以更改阴影偏移和模糊以更改阴影样式。如果您需要它变暗,您也可以依次添加和删除相同的cgpath,这将使阴影堆积起来。

    因此,在剪切上下文后,我将阴影应用到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,这将使阴影堆积起来。

        3
  •  7
  •   Alexey Golikov    11 年前

    我用fxlabel做内阴影,看这里 https://github.com/nicklockwood/FXLabel .

        4
  •  2
  •   James Snook    11 年前

    是的,我有一篇关于它的博客文章 here . 简单的答案是借用jtainnershadowlayer here ,为uilabel子类,并通过重写来更改其layerClass + (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
  •  0
  •   Community uzul    7 年前

    你将不得不做你自己的自定义绘图,以获得一个内部阴影。目前没有办法使用标准的uilabel。

    下面是一个关于用石英做内阴影的合理解释。

    Inner shadow in Core Graphics

        6
  •  0
  •   KarenAnne    10 年前

    尝试 PaintCode 试用版!对于初学者,您将学习如何创建自定义绘图。非常好!:3您可以使用它进行练习或学习,但不要一直使用它,您还应该学习如何自己创建图形。

    免责声明:我不是一个代言人,我只是惊讶于我的发现。;)