2012-08-14 62 views
0

我創建了覆蓋[text | editing | placeholder] RectForBounds的所有UITextField的子類:(全部使用完全相同的實現)。當從代碼實例化時,一切正常,但不是從nib加載時。在從筆尖加載的文本字段上,不會繪製文本和佔位符。textRectForBounds:在從Nib加載的自定義UITextField上未調用

我注意到,直到用戶點擊文本字段時纔會調用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

你重寫了initWithFrame嗎?如果是這樣的話,你還需要重寫initWithCoder :,這是UINib的入口。 – 2012-08-14 13:29:53

+0

是的,我沒有覆蓋initWithCoder :.除了文字,一切看起來都很好。 – Austin 2012-08-14 14:14:38

+0

今晚我會看看它。 – 2012-08-14 14:29:10

回答

0

的問題是,蘋果公司的代碼花費的initWithCoder和initWithFrame稍有不同的路徑,因此它的調用此方法一旦不相關的placeholderstring。

所以在我的測試中,我有兩個標籤,一個用代碼創建,一個用於筆尖,兩者都有相當長的佔位符字符串。

核心問題與'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個點。你需要對此進行解釋。

+0

感謝您的回答。我設置了一個斷點,並發現layoutSubviews被調用(可能是由於格式化視圖控制器中的代碼和nib中的用戶定義的鍵值對)。我嘗試了很好的解決方案,但仍然沒有繪製文本。 – Austin 2012-08-15 12:37:33

+0

Ooops - 我太專注於讓RectForBounds方法出現並忘記顯示文本 - 我會再看看我的代碼。你能否澄清「沒有文字」 - 你在筆尖有一個什麼樣的文本(佔位符?文本?) – 2012-08-15 12:59:09

+0

在文本字段中沒有文字開始,但是當我點擊該字段並開始輸入時,文本和光標沒有畫出來。我可以鍵入並讀回數值,只是沒有看到它。另外,當我按住場地時,放大鏡中沒有任何東西。 – Austin 2012-08-15 15:13:44

相關問題