Is it possible to draw text with shadows using the NSString UIKit additions?

前端 未结 2 2047
余生分开走
余生分开走 2021-01-01 21:20

Is it possible to draw with simple text shadows when using the NSString UIKit additions? I mean without writing code to draw twice in two colors, as can be done with various

相关标签:
2条回答
  • 2021-01-01 21:54

    The following snippet uses CALayer to add shadow around the edges of the characters in a UILabel:

     _helloLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320, 30)];
    [_helloLabel setBackgroundColor:[UIColor clearColor]];
    [_helloLabel setTextColor:[UIColor whiteColor]];
    [_helloLabel setTextAlignment:NSTextAlignmentCenter];
    [_helloLabel setFont:[UIFont lightApplicationFontOfSize:30]];
    
    _helloLabel.layer.shadowColor = UIColorFromRGB(0xd04942).CGColor;
    _helloLabel.layer.shadowOffset = CGSizeMake(0, 0);
    _helloLabel.layer.shadowRadius = 2.0;
    _helloLabel.layer.shadowOpacity = 1.0;
    
    [self addSubview:_helloLabel];
    

    . . normally this would add a shadow around the border, but UILabel seems to treat these properties as a special case.

    0 讨论(0)
  • 2021-01-01 22:02

    A couple of thoughts:

    1. The UITextAttributeTextShadow... keys are intended for when using a text attribute dictionary with, for example, UIAppearance methods:

      NSDictionary *attributes = @{UITextAttributeTextShadowColor  : [UIColor blackColor],
                                   UITextAttributeTextShadowOffset : [NSValue valueWithUIOffset:UIOffsetMake(2.0, 0.0)],
                                   UITextAttributeTextColor        : [UIColor yellowColor]};
      
      [[UINavigationBar appearance] setTitleTextAttributes:attributes];
      

      The UITextAttributeTextShadow... keys are designed for use only in those methods that accept a text attributes dictionary.

    2. The closest equivalent key when drawing text strings is the use of attributed strings with the NSShadowAttributeName key:

      - (void)drawRect:(CGRect)rect
      {
          UIFont *font = [UIFont systemFontOfSize:50];
      
          NSShadow *shadow = [[NSShadow alloc] init];
          shadow.shadowColor = [UIColor blackColor];
          shadow.shadowBlurRadius = 0.0;
          shadow.shadowOffset = CGSizeMake(0.0, 2.0);
      
          NSDictionary *attributes = @{NSShadowAttributeName          : shadow,
                                       NSForegroundColorAttributeName : [UIColor yellowColor],
                                       NSFontAttributeName            : font};
      
          NSAttributedString *attributedText = [[NSAttributedString alloc] initWithString:@"this has shadows" attributes:attributes];
      
          [attributedText drawInRect:rect];
      }
      

      If you're concerned about the performance hit of a shadow algorithm capable of doing a bezier curve shadow, though, NSShadow may suffer from that. But doing some benchmarks, changing the shadowBlurRadius dramatically affects performance. For example, animating the rotation of a complex multi-line text with a shadowBlurRadius of 10.0 on a slow iPhone 3GS achieved a frame rate of 31 fps, but changing shadowBlurRadius to 0.0 yielded a frame rate of 60 fps.

      Bottom line, using a shadow blur radius of 0.0 eliminates most (if not all) of the computational overhead of a bezier generated shadow.

    3. FYI, I experience a similar performance improvement by setting the blur value to 0.0 for CGContextSetShadow, just like I experienced with the attributed text rendition above.

    Bottom line, I don't think you should fear the computational overhead of bezier-based shadows as long as you use a blur radius of 0.0. I wouldn't be surprised if writing the text twice yourself, once for the shadow and again for the foreground color, might even be a bit more efficient, but I'm not sure if the difference will be observable. But I don't know of any API call that will do that for you (other than CGContextSetShadow with blur of 0.0).

    0 讨论(0)
提交回复
热议问题