2012-08-01 226 views
5

我想用阴影在UITextField中绘制文本。为了做到这一点,我有子类的UITextField,并执行如下的方法drawTextInRect:编辑时不显示UITextField阴影

- (void)drawTextInRect:(CGRect)rect { 
    CGContextRef context = UIGraphicsGetCurrentContext(); 

    // Create shadow color 
    float colorValues[] = {0.21875, 0.21875, 0.21875, 1.0}; 
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 
    CGColorRef shadowColor = CGColorCreate(colorSpace, colorValues); 
    CGColorSpaceRelease(colorSpace); 

    // Create shadow 
    CGSize shadowOffset = CGSizeMake(2, 2); 
    CGContextSetShadowWithColor(context, shadowOffset, 0, shadowColor); 
    CGColorRelease(shadowColor); 

    // Render text 
    [super drawTextInRect:rect];  
} 

这个伟大的工程当文本字段不为编辑,但只要开始编辑,阴影消失。有什么我失踪?

+0

我以前见过这个Mac OS X上,而在这种情况下,这是因为字段编辑器并没有抓住黑影从'NSTextField'属性,因此没有表现出阴影。不知道iOS中是否有字段编辑器,但我想我会发表评论。 – Vervious 2012-08-01 02:53:07

+0

我做了一些Google搜索,它看起来不像UITextFields使用字段编辑器,所以忽略我以前的评论。 – Vervious 2012-08-01 02:55:37

+0

你确实意识到,在iOS上这个小小的文本上添加阴影会使文本几乎不可读。 – 2012-08-09 02:22:37

回答

0

您可以尝试自己绘制标签。删除

[super drawTextInRect:rect] 

而是绘制自己的标签。我还没有试过,但它可能是这个样子:

// Declare a label as a member in your class in the .h file and a property for it: 
UILabel *textFieldLabel; 
@property (nonatomic, retain) UILabel *textFieldLabel; 

// Draw the label 
- (void)drawTextInRect:(CGRect)rect { 
    if (self.textFieldLabel == nil) { 
     self.textFieldLabel = [[[UILabel alloc] initWithFrame:rect] autorelease]; 
     [self.view addSubview:myLabel]; 
    } 

    self.textFieldLabel.frame = rect; 
    self.textFieldLabel.text = self.text; 

    /** Set the style you wish for your label here **/ 
    self.textFieldLabel.shadowColor = [UIColor grayColor]; 
    self.textFieldLabel.shadowOffset = CGSizeMake(2,2); 
    self.textFieldLabel.textColor = [UIColor blueColor]; 

    // Do not call [super drawTextInRect:myLabel] method if drawing your own text 
} 
1

这里是代码以下组件

enter image description here

@interface AZTextField() 
- (void)privateInitialization; 
@end 

@implementation AZTextField 

static CGFloat const kAZTextFieldCornerRadius = 3.0; 

- (id)initWithFrame:(CGRect)frame 
{ 

    self = [super initWithFrame:frame]; 
    if (!self) return nil; 
    [self privateInitialization]; 
    return self; 
} 

// In case you decided to use it in a nib 
- (id)initWithCoder:(NSCoder *)aDecoder 
{ 
    self = [super initWithCoder:aDecoder]; 
    if (!self) return nil; 
    [self privateInitialization]; 
    return self; 
} 

- (void)privateInitialization 
{ 
    self.borderStyle = UITextBorderStyleNone; 

    self.layer.masksToBounds = NO; 
    self.layer.shadowColor = [UIColor blackColor].CGColor; 
    self.layer.shadowOffset = CGSizeMake(0.0f, 5.0f); 
    self.layer.shadowOpacity = 0.5f; 

    self.layer.backgroundColor = [UIColor whiteColor].CGColor; 
    self.layer.cornerRadius = 4; 

    // This code is better to be called whenever size of the textfield changed, 
    // so if you plan to do that you can add an observer for bounds property 
    UIBezierPath *shadowPath = [UIBezierPath bezierPathWithRoundedRect:self.bounds cornerRadius:kAZTextFieldCornerRadius]; 
    self.layer.shadowPath = shadowPath.CGPath; 
} 

@end 

夫妇的事情要考虑:

  • 您想将borderStyle设置为none,否则最终会以 UIKit的将子视图插入文本框
  • 根据Xcode的 版本,你会想要连结QuartzCore和#import <QuartzCore/QuartzCore.h>
  • 对于更复杂的外观,你仍然可以在层的 使用阴影属性和绘图代码本身 移入drawRect:方法,但jake_hetfield是正确的,如果你 重写的drawRect你不想叫超,尤其是在方法
  • 至于文本绘制结束 (你可以看到,它坚持 接近组件边界),你有一个单独的 drawTextInRect:和绘制 文字和占位符分别为
  • 可以使用的UIColor方法 颜色和呼叫CGColor财产drawPlaceholderInRect:方法,它使代码更易读和 易于维护

希望帮助!

0

停止调用super并自己渲染文本。

1

通过@jake_hetfield答案启发我创建了一个自定义的UITextField使用内部标签做图纸,检查出来:

ShadowTextField .h文件中

#import <UIKit/UIKit.h> 

@interface ShadowTextField : UITextField 

// properties to change the shadow color & offset 
@property (nonatomic, retain) UIColor *textShadowColor; 
@property (nonatomic) CGSize textShadowOffset; 

- (id)initWithFrame:(CGRect)frame 
       font:(UIFont *)font 
      textColor:(UIColor *)textColor 
     shadowColor:(UIColor *)shadowColor 
     shadowOffset:(CGSize)shadowOffset; 

@end 

ShadowTextField。M档

#import "ShadowTextField.h" 

@interface ShadowTextField() 
@property (nonatomic, retain) UILabel *internalLabel; 
@end 

@implementation ShadowTextField 
@synthesize internalLabel = _internalLabel; 
@synthesize textShadowColor = _textShadowColor; 
@synthesize textShadowOffset = _textShadowOffset; 

- (id)initWithFrame:(CGRect)frame 
       font:(UIFont *)font 
      textColor:(UIColor *)textColor 
     shadowColor:(UIColor *)shadowColor 
     shadowOffset:(CGSize)shadowOffset 
{ 
    self = [super initWithFrame:frame]; 
    if (self) { 
     // Initialization code 

     // register to my own text changes notification, so I can update the internal label 
     [[NSNotificationCenter defaultCenter] addObserver:self 
               selector:@selector(handleUITextFieldTextDidChangeNotification) 
                name:UITextFieldTextDidChangeNotification 
                object:nil]; 

     self.font = font; 
     self.textColor = textColor; 

     self.textShadowColor = shadowColor; 
     self.textShadowOffset = shadowOffset; 
    } 
    return self; 
} 

// when the user enter text we update the internal label 
- (void)handleUITextFieldTextDidChangeNotification 
{ 
    self.internalLabel.text = self.text; 

    [self.internalLabel sizeToFit]; 
} 

// init the internal label when first needed 
- (UILabel *)internalLabel 
{ 
    if (!_internalLabel) { 
     _internalLabel = [[UILabel alloc] initWithFrame:self.bounds]; 
     [self addSubview:_internalLabel]; 

     _internalLabel.font = self.font; 
     _internalLabel.backgroundColor = [UIColor clearColor]; 
    } 
    return _internalLabel; 
} 

// override this method to update the internal label color 
// and to set the original label to clear so we wont get two labels 
- (void)setTextColor:(UIColor *)textColor 
{ 
    [super setTextColor:[UIColor clearColor]]; 

    self.internalLabel.textColor = textColor; 
} 

// override this method to update the internal label text 
- (void)setText:(NSString *)text 
{ 
    [super setText:text]; 

    self.internalLabel.text = self.text; 

    [self.internalLabel sizeToFit]; 
} 

- (void)setTextShadowColor:(UIColor *)textShadowColor 
{ 
    self.internalLabel.shadowColor = textShadowColor; 
} 

- (void)setTextShadowOffset:(CGSize)textShadowOffset 
{ 
    self.internalLabel.shadowOffset = textShadowOffset; 
} 

- (void)drawTextInRect:(CGRect)rect { 
    // don't draw anything 
    // we have the internal label for that... 
} 

- (void)dealloc { 
    [_internalLabel release]; 
    [_textShadowColor release]; 

    [super dealloc]; 
} 

@end 

这里是你如何使用它在您的视图控制器

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    ShadowTextField *textField = [[ShadowTextField alloc] initWithFrame:CGRectMake(0, 0, 320, 30) 
                    font:[UIFont systemFontOfSize:22.0] 
                   textColor:[UIColor whiteColor] 
                  shadowColor:[UIColor redColor] 
                  shadowOffset:CGSizeMake(0, 1) ] ; 
    textField.text = @"This is some text";  
    textField.backgroundColor = [UIColor blackColor]; 
    [self.view addSubview:textField]; 
} 
0

有你与CALayer的标准阴影属性试过吗?它通常就够了,而且更简单。用普通的UITextField试试这样的:

self.inputContainer.layer.shadowColor=[UIColor blackColor].CGColor; 
self.inputContainer.layer.shadowRadius=8.0f; 
self.inputContainer.layer.cornerRadius=8.0f; 
self.inputContainer.layer.shadowOffset=CGSizeMake(0, 4); 

你需要首先导入QuartzCore!

#import <QuartzCore/QuartzCore.h> 
+0

*文字*的阴影,而不是整个视图。 – conradev 2012-08-10 16:47:27

+0

嗯,对!我的坏,对不起! – 2012-08-11 21:58:00