Ashish Awaghad
Ashish Awaghad

Reputation: 2822

UITextField doesn't scroll to the end after implementing textRectForBounds and editingRectForBounds in a subclass?

I have a UITextField subclass where I am implementing the methods below:

- (CGRect)textRectForBounds:(CGRect)bounds {

  return CGRectInset(bounds , 30, 7);
}

-(CGRect) editingRectForBounds:(CGRect)bounds {
  return CGRectInset(bounds , 30, 7);
}

Because of these two methods, the UITextField doesn't scroll to the end when the text entered gets bigger than the width of UITextField. Is there any solution to this?

Upvotes: 21

Views: 1661

Answers (5)

if-else-switch
if-else-switch

Reputation: 977

Its not working just because of the font size of the text you have declared in UITextField and the CGRectInset you are applying. Actually it should be as per the font size you are setting. For example, for font size of 14.0, just change your method as below:

- (CGRect)textRectForBounds:(CGRect)bounds {
    return CGRectInset(bounds , 30, 6);
}
-(CGRect) editingRectForBounds:(CGRect)bounds {
    return CGRectInset(bounds , 30, 6);
}

The reason is that the drawing rectangle of the text. For example, when we set font size of UITextField as 14.0 then it requires at least a height of 18.0 to adjust the text in the frame. So it needs 4 pixel extra around the text, you can say it overlay frame. Due to which, in your case, this condition is not satisfying because as far as I guess you have adjusted the font size to 14.0 and as by default frame height of UITextField is 30.0 and your edge masking is of 7.0 each side that means total 14.0. So your rect for text returns 16.0 which in turn blocks the OS from updating the text frame because it is outside of the graphics context. I hope you are clear.

More good answer will be as follows:

- (CGRect)textRectForBounds:(CGRect)bounds {
return CGRectInset(bounds , 30, (30 - self.font.pointSize - 4)/2);
}

-(CGRect) editingRectForBounds:(CGRect)bounds {
    return CGRectInset(bounds , 30, (30 - self.font.pointSize - 4)/2);
}

Upvotes: 12

Vinaykrishnan
Vinaykrishnan

Reputation: 768

step 1 - make a custom text field MyTextField first

@interface MyTextField : UITextField
step 2 - override MyTextField methods as per your requirement

///place holder position

- (CGRect)placeholderRectForBounds:(CGRect)bounds
 {
   return CGRectInset(bounds, 8, 8);
 }
 // text position
 - (CGRect)textRectForBounds:(CGRect)bounds {

  return CGRectInset(bounds, 8,4);
 }

 // text position while editing
 - (CGRect)editingRectForBounds:(CGRect)bounds {

     return CGRectInset(bounds, 8, 4);
 }
step 3- import MyTextField in your controller class & make object of MyTextField

#import "MyTextField.h"

-(void) viewWillAppear:(BOOL)animated {

    MyTextField* textfield1 = [[MyTextField alloc] init];
    // and so on

}

With Reference to this link :

- (CGRect) textRectForBounds:(CGRect)bounds not being called

Upvotes: 0

Yogendra
Yogendra

Reputation: 1716

Reason - You are using fixed font size for textfield text. Use this

 textFieldObject.adjustsFontSizeToFitWidth = YES;  

Short and simple. If you want to set your minimum font size you can use this

 textFieldObject.minimumFontSize

Enjoy

Upvotes: 2

Shai
Shai

Reputation: 25595

I'm not sure this is what you're looking for, but modifying editingRectForBounds the following way, will make the inset dynamic so once the textbox get's "full", it will lessen the inset so the text will fill the whole textbox.

assuming textInset_ is the wanted inset:

- (CGRect)editingRectForBounds:(CGRect)bounds {
    CGFloat compensate = .0f;
    CGSize size = [self.text sizeWithFont:self.font];
    CGFloat textboxWidth = CGRectGetWidth(self.width);

    // If size of text plus inset (right side) is bigger
    // than textbox's width, don't set an inset
    if (size.width+textInset_ >= textboxWidth) {
        compensate = 0;
    }

    // If text area (textbox width minus two insets) is less than
    // text size, lessen the inset so the text fits in 
    else if (textboxWidth - textInset_*2 < size.width) {
        compensate = fabs(size.width - (textboxWidth - textInset_));
    }

    // Text fits in textbox WITH insets
    else {
        compensate = textInset_;
    }
    return CGRectInset(bounds, compensate, 10);
}

Upvotes: 0

Douglas Ferreira
Douglas Ferreira

Reputation: 2279

This is probably a conflict between your custom UITextField CALayer height with insets and it's font size.

You may try one of these adjusts:

  • Decrease font size;
  • Increase the UITextField height on Storyboard or programmatically in your subclass like:

    - (void)drawRect:(CGRect)rect {
        CGRect frameRect = self.frame;
        frameRect.size.height = 35 //specify the height you want;
        self.frame = frameRect;
     }
    
  • Decrease the y-coordinate value on CGRectInset;

  • Or use UIEdgeInsets to have more control in setting values ​​of each position. Something like:

    - (CGRect)textRectForBounds:(CGRect)bounds{
        UIEdgeInsets contentInsets = UIEdgeInsetsMake(5, 30, 5, 30);
        return UIEdgeInsetsInsetRect(bounds, contentInsets);
    }
    
    - (CGRect)editingRectForBounds:(CGRect)bounds{
        UIEdgeInsets contentInsets = UIEdgeInsetsMake(5, 30, 5, 30);
        return UIEdgeInsetsInsetRect(bounds, contentInsets);
    }
    

Upvotes: 4

Related Questions