444 Stimmen

Texteinschub für UITextField?

Ich würde gerne die Text eines UITextField .

Ist dies möglich?

1 Stimmen

3voto

Noah Witherspoon Punkte 56607

Sie können die Positionierung des Textes innerhalb eines Textfeldes anpassen, indem Sie es zu einer Unterklasse von UITextField und die Überschreibung der -textRectForBounds: método.

2voto

hasan Punkte 22989

Eine Lösung, die tatsächlich funktioniert und alle Fälle abdeckt:

  • Sollte verwenden offsetBy no insetBy .
  • Sollte auch die Superfunktion aufrufen, um das Original zu erhalten Rect .
  • Bounds ist fehlerhaft. Sie müssen die ursprünglichen X, Y ausgleichen. Bounds haben X, Y als Nullen.
  • Original x, y können ungleich Null sein, z.B. beim Setzen der leftView des UITextFields.

Beispiel:

override func textRect(forBounds bounds: CGRect) -> CGRect {
    return super.textRect(forBounds: bounds).offsetBy(dx: 0.0, dy: 4)
}

override func editingRect(forBounds bounds: CGRect) -> CGRect {
    return super.editingRect(forBounds: bounds).offsetBy(dx: 0.0, dy: 4)
}

2voto

Ich fand die von roberto.buratti gepostete Option die schnellste Lösung, hier ist sie in Swift:

let leftView = UIView(frame: CGRect(x: 0, y: 0, width: 10, height: textField.frame.size.height))
leftView.backgroundColor = textField.backgroundColor
textField.leftView = leftView
textField.leftViewMode = UITextField.ViewMode.always

2voto

user3878720 Punkte 21

Dieses Beispiel ist nicht so kurz wie die anderen, aber es verfolgt einen ganz anderen Ansatz zur Lösung des Problems. Beachten Sie, dass die Einfügemarke immer noch bündig mit dem linken Rand beginnt, aber der Text wird bei der Eingabe/Anzeige richtig eingerückt. Dies funktioniert ohne Unterklassenbildung, wenn Sie nur einen linken Rand suchen und bereits UITextFieldDelegate für Ihre Textfelder. Sie müssen sowohl die Standardtextattribute als auch die Attribute für die Eingabe festlegen. Sie legen die Standardtextattribute fest, wenn Sie das Textfeld erstellen. Die Attribute für die Eingabe müssen Sie im Delegaten festlegen. Wenn Sie auch einen Platzhalter verwenden, müssen Sie diesen ebenfalls auf denselben Rand setzen. Zusammengenommen erhalten Sie so etwas wie dies.

Erstellen Sie zunächst eine Kategorie auf der Registerkarte UITextField Klasse.

//  UITextField+TextAttributes.h

#import <UIKit/UIKit.h>

@interface UITextField (TextAttributes)

- (void)setIndent:(CGFloat)indent;

@end

//  UITextField+TextAttributes.m
#import "UITextField+TextAttributes.h"

@implementation UITextField (TextAttributes)

- (void)setTextAttributes:(NSDictionary*)textAttributes indent:(CGFloat)indent
{
    if (!textAttributes) return;

    NSMutableParagraphStyle *paragraphStyle = [textAttributes objectForKey:NSParagraphStyleAttributeName];
    paragraphStyle.firstLineHeadIndent = indent;
    paragraphStyle.headIndent = indent;
}

- (void)setIndent:(CGFloat)indent
{
   [self setTextAttributes:self.defaultTextAttributes indent:indent];
   [self setTextAttributes:self.typingAttributes indent:indent];
}

@end

Wenn Sie dann platzierte Platzhalter verwenden, stellen Sie sicher, dass Sie einen attributierten Platzhalter mit demselben Einzug verwenden. Erstellen Sie ein Standard-Attribut-Wörterbuch mit den richtigen Attributen, etwa so:

NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.firstLineHeadIndent = 7;
paragraphStyle.headIndent = 7;
NSDictionary *placeholderAttributes = [NSDictionary dictionaryWithObjectsAndKeys: paragraphStyle, NSParagraphStyleAttributeName, nil];

Importieren Sie dann die oben genannte Kategorie und legen Sie bei der Erstellung eines Textfelds den Standardeinzug und den Delegaten fest und verwenden Sie die oben definierten Standardattribute für Platzhalter. Zum Beispiel:

UITextField *textField = [[UITextField alloc] init];
textField.indent = 7;
textField.delegate = self;
textField.attributedPlaceholder = [[NSAttributedString alloc] initWithString:@"Placeholder Text" attributes:placeholderAttributes];

Schließlich implementieren Sie im Delegaten die textFieldDidBeginEditing Methode, etwa so:

- (void)textFieldDidBeginEditing:(UITextField *)textField
{
    textField.indent = 7;
}

0 Stimmen

Die Annahme, dass defaultTextAttributes enthält NSMutableParagraphStyle ist ziemlich gefährlich Ich würde lieber mutableCopy all dies.

2voto

Firula Punkte 1241

Ich subclased UITextField, dies zu behandeln, die links, oben, rechts und unten einfügen, und klare Schaltfläche Positionierung als gut unterstützt.

MRDInsetTextField.h

#import <UIKit/UIKit.h>

@interface MRDInsetTextField : UITextField

@property (nonatomic, assign) CGRect inset;

@end

MRDInsetTextField.m

#import "MRDInsetTextField.h"

@implementation MRDInsetTextField

- (id)init
{
    self = [super init];
    if (self) {
        _inset = CGRectZero;
    }
    return self;
}

- (id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder:aDecoder];
    if (self) {
        _inset = CGRectZero;
    }
    return self;
}

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        _inset = CGRectZero;
    }
    return self;
}

- (void)setInset:(CGRect)inset {
    _inset = inset;

    [self setNeedsLayout];
}

- (CGRect)getRectForBounds:(CGRect)bounds withInset:(CGRect)inset {

    CGRect newRect = CGRectMake(
                         bounds.origin.x + inset.origin.x,
                         bounds.origin.y + inset.origin.y,
                         bounds.origin.x + bounds.size.width - inset.origin.x - inset.size.width,
                         bounds.origin.y + bounds.size.height - inset.origin.y - inset.size.height
                         );

    return newRect;
}

- (CGRect)textRectForBounds:(CGRect)bounds {
    return [self getRectForBounds:[super textRectForBounds:bounds] withInset:_inset];
}

- (CGRect)placeholderRectForBounds:(CGRect)bounds {
    return [self getRectForBounds:bounds withInset:_inset];
}

- (CGRect)editingRectForBounds:(CGRect)bounds {
    return [self getRectForBounds:[super editingRectForBounds:bounds] withInset:_inset];
}

- (CGRect)clearButtonRectForBounds:(CGRect)bounds {
    return CGRectOffset([super clearButtonRectForBounds:bounds], -_inset.size.width, _inset.origin.y/2 - _inset.size.height/2);
}

@end

Beispiel für die Verwendung von *_someTextField* aus der Nib/Storyboard-Ansicht mit MRDInsetTextField benutzerdefinierte Klasse

[(MRDInsetTextField*)_someTextField setInset:CGRectMake(5, 0, 5, 0)]; // left, top, right, bottom inset

0 Stimmen

Ich danke Ihnen. Eine Anregung zu Ihrem Code aber - warum haben Sie CGRect für Inset und nicht UIEdgeInsets verwenden?

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X