我创建了一个UITextField的子类,它覆盖了[text | editing | placeholder] RectForBounds :(所有具有完全相同的实现)。从代码实例化时一切正常,但从笔尖加载时却没有。在从笔尖加载的文本字段中,既不绘制文本也不绘制占位符。
我注意到在用户点击文本字段之前不会调用任何RectForBounds方法;点击,编辑&使用正确的边界大小({{0,0},{300,39}})调用placeholderRectForBounds,而使用({{0,0},{100,100}})调用textRectForBounds。
那么,为什么文本从未被绘制(并且仅在从笔尖加载的字段中)?我做错了什么,或者这是UITextField的错误?
编辑:
以下是代码:
#import "SearchTextField.h"
#import <QuartzCore/QuartzCore.h>
#define BUTTON_WIDTH 50
#define MAX_LABEL_WIDTH 200
@interface SearchTextField ()
@property(retain, nonatomic) UILabel *label;
@property(retain, nonatomic) UIButton *button;
- (void)i_baseInit;
@end
@implementation SearchTextField
@synthesize title = _title;
@synthesize label = label_;
@synthesize button = button_;
@synthesize showButton = _showButton;
@synthesize backgroundView = _my_backgroundView;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
_showButton = YES;
[self i_baseInit];
}
return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder
{
if (self = [super initWithCoder:aDecoder])
{
[self i_baseInit];
}
return self;
}
- (void)i_baseInit
{
self.opaque = NO;
self.textAlignment = UITextAlignmentRight;
self.leftViewMode = UITextFieldViewModeAlways;
self.rightViewMode = UITextFieldViewModeAlways;
self.backgroundColor = [UIColor clearColor];
_my_backgroundView = [[MyView alloc] init];
self.backgroundView.backgroundColor = [UIColor whiteColor];
self.label = [[[UILabel alloc] init] autorelease];
self.label.font = [UIFont fontWithName:@"HelveticaNeue-CondensedBold" size:15];
self.label.textColor = [UIColor darkGrayColor];
self.label.textAlignment = UITextAlignmentRight;
self.label.backgroundColor = [UIColor clearColor];
self.label.text = _title;
self.leftView = self.label;
self.button = [UIButton buttonWithType:UIButtonTypeCustom];
[self.button setBackgroundImage:[UIImage imageNamed:@"button_sm"]
forState:UIControlStateNormal];
[self.button setBackgroundImage:[UIImage imageNamed:@"button_sm_pressed"]
forState:UIControlStateHighlighted];
self.button.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleLeftMargin;
self.button.hidden = !_showButton;
self.rightView = self.button;
}
- (void)drawRect:(CGRect)rect
{
self.backgroundView.frame = CGRectMake(self.bounds.origin.x,
self.bounds.origin.y,
self.bounds.size.width-1, // Without this, the background sticks out 1 pt from the button
self.bounds.size.height);
[self.backgroundView drawRect:rect];
}
- (id)copy
{
SearchTextField *copy = [[self.class alloc] initWithFrame:self.frame];
copy.text = self.text;
copy.textAlignment = self.textAlignment;
copy.textColor = self.textColor;
copy.placeholder = self.placeholder;
copy.background = self.background;
copy.backgroundColor = self.backgroundColor;
copy.borderStyle = self.borderStyle;
copy.font = self.font;
copy.showButton = self.showButton;
copy.title = self.title;
copy.delegate = self.delegate;
copy.secureTextEntry = self.secureTextEntry;
copy.returnKeyType = self.returnKeyType;
copy.keyboardType = self.keyboardType;
return copy;
}
#pragma mark - UITextField Positioning -
- (CGRect)textRectForBounds:(CGRect)bounds
{
CGSize labelSize = [self.label.text sizeWithFont:self.label.font constrainedToSize:CGSizeMake(MAX_LABEL_WIDTH, bounds.size.height)];
CGSize textSize = [@"Test" sizeWithFont:self.font];
CGRect rect = CGRectMake(10 + labelSize.width,
(bounds.size.height-textSize.height)/2,
bounds.size.width - (20 + labelSize.width + ((self.showButton) ? BUTTON_WIDTH : 0)),
textSize.height);
return rect;
}
- (CGRect)placeholderRectForBounds:(CGRect)bounds
{
return [self textRectForBounds:bounds];
}
- (CGRect)editingRectForBounds:(CGRect)bounds
{
return [self textRectForBounds:bounds];
}
- (CGRect)leftViewRectForBounds:(CGRect)bounds
{
return CGRectMake(10,
0,
[self.label.text sizeWithFont:self.label.font constrainedToSize:CGSizeMake(MAX_LABEL_WIDTH, bounds.size.height)].width,
bounds.size.height);
}
- (CGRect)rightViewRectForBounds:(CGRect)bounds
{
if (!self.showButton) { return CGRectZero; }
return CGRectMake(bounds.size.width-BUTTON_WIDTH,
0,
BUTTON_WIDTH,
bounds.size.height);
}
#pragma mark -
- (void)setTitle:(NSString *)title
{
[_title release];
_title = [title retain];
self.label.text = title;
[self setNeedsLayout];
}
- (UIImage *)imageForState:(UIControlState)state
{
return [self.button imageForState:state];
}
- (void)setImage:(UIImage *)image forState:(UIControlState)state
{
[self.button setImage:image forState:state];
}
- (void)addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents
{
[self.button addTarget:target action:action forControlEvents:controlEvents];
}
- (void)setShowButton:(BOOL)showButton
{
self.button.hidden = !showButton;
_showButton = showButton;
[self setNeedsLayout];
}
- (MyView *)backgroundView
{
[self setNeedsDisplay];
return _my_backgroundView;
}
- (void)dealloc
{
[_my_backgroundView release];
[label_ release];
[button_ release];
[super dealloc];
}
@end
答案 0 :(得分:0)
问题在于,对于Apple的代码,initWithCoder和initWithFrame的路径略有不同,因此它调用此方法一次与占位符字符串无关。
因此,在我的测试中,我有两个标签,一个在代码中创建,一个在笔尖中,两个都有一个相当长的占位符字符串。
核心问题与'textRectForBounds:'有关,因为还有一个与显示的占位符无关的附加消息。不仅如此,但边界很大,这导致你返回一个超出控件范围的矩形。我不太了解您的代码以提出解决方案,但至少您现在知道要解决的问题。
使用此附加日志记录:
- (CGRect)textRectForBounds:(CGRect)bounds
{
CGRect rect ;
rect = [super textRectForBounds:bounds];
NSLog(@"REAL textRectForBounds %@", NSStringFromCGRect(rect) );
CGSize labelSize = [self.label.text sizeWithFont:self.label.font constrainedToSize:CGSizeMake(MAX_LABEL_WIDTH, bounds.size.height)];
CGSize textSize = [@"Test" sizeWithFont:self.font];
NSLog(@"labelSize=%@ textSize=%@ bounds=%@", NSStringFromCGSize(labelSize), NSStringFromCGSize(textSize), NSStringFromCGRect(bounds));
rect = CGRectMake(10 + labelSize.width,
(bounds.size.height-textSize.height)/2,
bounds.size.width - (20 + labelSize.width + ((self.showButton) ? BUTTON_WIDTH : 0)),
textSize.height);
NSLog(@"%@: textRectForBounds %@", type, NSStringFromCGRect(rect) );
return rect;
}
我所看到的是:
labelSize={0, 100} textSize={28, 18} bounds={{0, 0}, {100, 100}}
textRectForBounds {{10, 41}, {80, 18}}
因此系统由于某种原因传入100x100边界,然后您的代码创建一个矩形,其y偏移低于textField 10个点。您需要考虑到这一点。