A static character prefix in UITextField

一笑奈何 提交于 2019-12-06 19:46:21

问题


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.


回答1:


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.




回答2:


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];



回答3:


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.

Solution 1: Right Align the Dollar Sign

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, e.g., due to Auto Layout (or autoresizing).

Solution 2: Subclass UITextField & Override Its Positioning

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

Conclusion

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.




回答4:


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.




回答5:


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.



来源:https://stackoverflow.com/questions/11285502/a-static-character-prefix-in-uitextfield

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!