Is there a built-in way to add a character prefix to a UITextField
like the screenshot below?
If no, what is the best, most straight-forward way to accomplish this? I am thinking the background
property might be able to do this.
Simply adding a gray UILabel
on top of the UITextField
does the trick:
Note that the UILabel
behaves like a background image, the entered text stays on top:
UPDATE
Additionally you can add some padding to the UITextField
using the following code:
UIView *thePadding = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 5, 20)];
theTextField.leftView = thePadding;
theTextField.leftViewMode = UITextFieldViewModeAlways;
This way the text cannot cover the prefix character.
Adjust the rect to make it working properly in your situation.
Following on from Anne's code you can also do this directly in code without the UILabel in IB and UIView in code:
UILabel *poundLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 5, 20)];
poundLabel.text = @"£";
[self.paymentAmount setLeftView:poundLabel];
[self.paymentAmount setLeftViewMode:UITextFieldViewModeAlways];
With Ditiet's solution (on retina using size 15 system font), the text field positioned its text 0.5 points too close to the dollar sign. Using -sizeWithAttributes:
, I fit the width
of the dollar sign label to about 8.5 but the text field positioned its text at an x
of 8 (the floor of the left view's width).
I found two solutions to perfect the relative positioning between the dollar sign (left view) & text.
Set the dollar sign label's width to the ceiling of the width of the dollar sign (or hard code it). Then, right align the dollar sign label's text.
UIFont *font = [UIFont systemFontOfSize:15];
UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(100, 200, 120, 44)];
textField.font = font;
NSString *dollarSignText = @"$";
CGSize size = [dollarSignText sizeWithAttributes:@{NSFontAttributeName: font}];
UILabel *dollarSignLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, ceilf(size.width), 44)];
dollarSignLabel.font = font;
dollarSignLabel.text = dollarSignText;
dollarSignLabel.textAlignment = NSTextAlignmentRight;
textField.leftView = dollarSignLabel;
textField.leftViewMode = UITextFieldViewModeAlways;
[self.view addSubview:textField];
Although this solution perfects the relative positioning between the dollar sign label (left view) & text, it will likely increase the width of the dollar sign label a bit (not more than 1 pt), causing the same increase to the text field's width and shifting all the text to the right by the same amount.
I don't recommend this solution if the text field's height will change, eg, due to Auto Layout (or autoresizing).
This solution supports you're using Auto Layout (or autoresizing) to adjust the text field's height.
// VVMAmountTextField.h
@import UIKit;
@interface VVMAmountTextField : UITextField
@end
// VVMAmountTextField.m
#import "VVMAmountTextField.h"
@implementation VVMAmountTextField
#pragma mark - UIView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
UIFont *font = [UIFont systemFontOfSize:15];
self.font = font;
self.keyboardType = UIKeyboardTypeDecimalPad;
self.placeholder = @"0.00";
// Set leftView to dollarSignLabel ($).
UILabel *dollarSignLabel = [[UILabel alloc] initWithFrame:CGRectZero];
dollarSignLabel.backgroundColor = [UIColor whiteColor];
dollarSignLabel.font = font;
dollarSignLabel.text = @"$";
self.leftView = dollarSignLabel;
self.leftViewMode = UITextFieldViewModeAlways;
}
return self;
}
#pragma mark - UITextField
// Override positioning to make things pixel perfect.
#define DOLLAR_SIGN_WIDTH() [((UILabel *)self.leftView).text sizeWithAttributes:@{NSFontAttributeName: self.font}].width
- (CGRect)textRectForBounds:(CGRect)bounds
{
bounds = [super textRectForBounds:bounds];
bounds.origin.x = DOLLAR_SIGN_WIDTH();
return bounds;
}
- (CGRect)editingRectForBounds:(CGRect)bounds
{
bounds = [super editingRectForBounds:bounds];
bounds.origin.x = DOLLAR_SIGN_WIDTH();
return bounds;
}
- (CGRect)leftViewRectForBounds:(CGRect)bounds
{
bounds.size.width = DOLLAR_SIGN_WIDTH();
return bounds;
}
@end
Either solution seems to work well. Solution 1 will likely cause a shift but has less code and still looks pixel-perfect. I only thought of it after Solution 2. Solution 2 is elegant and supports you're using Auto Layout (or autoresizing) to adjust the text field's height.
Dont think you can do this as part of UITextField
alone.
One way I can thing of is to make your UITextField
borderless and keep a UILabel
on the left (but adjacent) of the UITextField
. And finally if you want border than put these 2 elements (UITextField and UILabel) inside a UIView and give border to this view. This setup should look exactly same as the image you have put up.
Let me know if this works out.
UPDATE : you could do as @Anne points but there is a risk of text running on top of the UILabel. I feel what I suggested is better.
To add to Anne's answer. You could also make it a UIImageView and use any image you want there. With a UIImageView you can set the background to be white so text will tuck underneath it.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.