在UITextField文本上添加阴影效果

55

UITextField 中给文本添加阴影是否可行?

4个回答

178

从3.2版本开始,您可以使用CALayer的阴影属性。

_textField.layer.shadowOpacity = 1.0;   
_textField.layer.shadowRadius = 0.0;
_textField.layer.shadowColor = [UIColor blackColor].CGColor;
_textField.layer.shadowOffset = CGSizeMake(0.0, -1.0);

1
非常好用。 在iPad上,您应该将偏移量更改为CGSizeMake(0.0,1.0),颜色更改为白色。 - Thomas
16
确实,这是最简单的解决方案。要使其工作,您需要导入#import <QuartzCore/QuartzCore.h> - Guillaume Boudreau
我使用了这段代码来为UILabel的文本应用阴影。完美地工作了!通过使用label.layer.shadowOpacity等属性,文本被加上了阴影。 - BBog
奇怪,我只能在UILabel上使用shadowColor和shadowOffset属性,而图层属性没有效果。我已经将QuartzCore添加到我的项目中。 - wprater
@wprater...你必须像Guillaume Boudreau之前所述那样导入<QuartzCore/QuartzCore.h>。仅仅导入是不够的。然后你就可以使用这些属性了。 - George

74

我有一个略微不同的问题 - 我想在UILabel上添加一个模糊阴影。幸运的是,这个问题的解决方案是Tyler的第二种方法。

这是我的代码:

- (void) drawTextInRect:(CGRect)rect {
    CGSize myShadowOffset = CGSizeMake(4, -4);
    CGFloat myColorValues[] = {0, 0, 0, .8};

    CGContextRef myContext = UIGraphicsGetCurrentContext();
    CGContextSaveGState(myContext);

    CGColorSpaceRef myColorSpace = CGColorSpaceCreateDeviceRGB();
    CGColorRef myColor = CGColorCreate(myColorSpace, myColorValues);
    CGContextSetShadowWithColor (myContext, myShadowOffset, 5, myColor);

    [super drawTextInRect:rect];

    CGColorRelease(myColor);
    CGColorSpaceRelease(myColorSpace); 

    CGContextRestoreGState(myContext);
}

这段代码是在继承自UILabel的类中实现,将文本向下和向右投影4像素,投影阴影的颜色为灰色,透明度为80%,并且稍微模糊。

我认为Tyler的解决方案2比解决方案1的性能略好——您只需要在视图中处理一个UILabel,并且假设您不会在每一帧都重新绘制,它对于普通的UILabel而言渲染性能不会受到影响。

PS:此代码大量借鉴了Quartz 2D文档


感谢您的代码!由于您正在调用CGContextSetShadowWithColor,因此可以删除CGContextSetShadow行。根据CGContext.h,CGContextSetShadow是“相当于调用CGContextSetShadowWithColor(context,offset,blur,color),其中颜色为带有1/3 alpha的黑色”。 - johnboiles
谢谢 - 我已经删除了那一行 - 典型的从示例中复制粘贴错误 :) - deanWombourne
"Quartz 2D documentation"链接已失效,新链接为:http://developer.apple.com/library/mac/#documentation/GraphicsImaging/Conceptual/drawingwithquartz2d/dq_shadows/dq_shadows.html。 - Vamos
谢谢你提供这个漂亮的代码片段。我已将其用于我的项目,并经过一些尝试,发现将'shadowOffset'设置为(0,0),'blur'设置为2,文本标签正好具有所需的投影效果。 - Yuanfei Zhu

18

我认为您在这里没有内置支持文本阴影的功能,就像UILabel一样。

有两个想法:

(1)[编码难度适中。]在原始文本框后面添加第二个UITextField,并将其略微偏移(例如(0.2,0.8)?)。您可以通过实现UITextFieldDelegate协议中的textField:shouldChangeCharactersInRange:replacementString:方法侦听每个按键的文本更改。利用此方法,您可以同时更新较低的文本(即阴影文本)。您还可以使用分数偏移文本矩形模糊滤镜,使较低的文本(即阴影文本)呈灰色,甚至略微模糊。添加:哦,是的,如果您采用此想法,请不要忘记将顶部文本字段的背景颜色设置为[UIColor clearColor]

(2) [更有趣的编码体验。] 子类化UITextField并覆盖drawRect:方法。我之前没有这样做过,所以需要提前说明的是,这取决于它是否是指定的绘图方法,可能会发现你需要覆盖另一个绘图函数,例如特定于UITextFielddrawTextInRect:。现在通过 CGContextSetShadow函数设置绘图上下文以绘制阴影,并调用[super drawRect:rect];。希望这能够起作用--如果原始的UITextField代码清除了绘图上下文的阴影参数,那么这个想法就失败了,你将不得不自己编写整个绘图代码。因为UITextFields附带的所有其他功能,如复制和粘贴和日语中的汉字输入,我建议您不要这样做。


2
你应该绝对使用来自egarc的下面的答案,这是解决这个问题的更好的方法! - Mac_Cain13
1
没错,@Mac_Cain13。那些CALayer属性是在iOS 3.2中添加的,而当我写下我的答案时,该版本尚未发布。 - Tyler

17
尽管将阴影直接应用于 UITextView 的方法可以起作用,但这是错误的方法。通过在具有清晰背景色的情况下直接添加阴影,所有子视图都将获得阴影,甚至包括光标。
应该使用的方法是使用 NSAttributedString
NSMutableAttributedString* attString = [[NSMutableAttributedString alloc] initWithString:textView.text];
NSRange range = NSMakeRange(0, [attString length]);

[attString addAttribute:NSFontAttributeName value:textView.font range:range];
[attString addAttribute:NSForegroundColorAttributeName value:textView.textColor range:range];

NSShadow* shadow = [[NSShadow alloc] init];
shadow.shadowColor = [UIColor whiteColor];
shadow.shadowOffset = CGSizeMake(0.0f, 1.0f);
[attString addAttribute:NSShadowAttributeName value:shadow range:range];

textView.attributedText = attString;

然而 textView.attributedText 是适用于iOS6的。如果您必须支持较低版本,可以使用以下方法。(不要忘记添加 #import <QuartzCore/QuartzCore.h>

CALayer *textLayer = (CALayer *)[textView.layer.sublayers objectAtIndex:0];
textLayer.shadowColor = [UIColor whiteColor].CGColor;
textLayer.shadowOffset = CGSizeMake(0.0f, 1.0f);
textLayer.shadowOpacity = 1.0f;
textLayer.shadowRadius = 0.0f;

3
粗糙中的钻石答案。 这比设置CALayer阴影属性要快得多。 - user
2
如果您添加 shadow.shadowBlurRadius = 6.f;,这也适用于将模糊效果添加到阴影。 - gavdotnet

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接