Legen Sie die Auffüllung für UITextField mit UITextBorderStyleNone fest

399

Ich wollte einen benutzerdefinierten Hintergrund für meine verwenden UITextFields. Dies funktioniert gut, bis auf die Tatsache, dass ich es verwenden muss UITextBorderStyleNone, damit es hübsch aussieht. Dadurch wird der Text gezwungen, ohne Auffüllung links zu bleiben.

Kann ich eine Auffüllung manuell so einstellen, dass sie ähnlich aussieht, UITextBorderStyleRoundedRectaußer dass mein benutzerdefiniertes Hintergrundbild verwendet wird?

Sebastian Wramba
quelle

Antworten:

837

Ich habe einen hübschen kleinen Hack gefunden, um die linke Polsterung genau auf diese Situation einzustellen.

Grundsätzlich legen Sie die leftView-Eigenschaft von so fest UITextField, dass sie eine leere Ansicht der Größe der gewünschten Auffüllung ist:

UIView *paddingView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 5, 20)];
textField.leftView = paddingView;
textField.leftViewMode = UITextFieldViewModeAlways;

Arbeitete wie ein Zauber für mich!

In Swift 3 / Swift 4 ist dies auf diese Weise möglich

let paddingView: UIView = UIView(frame: CGRect(x: 0, y: 0, width: 5, height: 20))
textField.leftView = paddingView
textField.leftViewMode = .always
Böse Forelle
quelle
1
Genau das, was ich brauchte, außer dass ich rechts Polster brauchte, was natürlich meistens das gleiche ist. Vielen Dank!
cg.
@ Lukasas Ich habe dieser Antwort eine Autorelease hinzugefügt, die akzeptierte Antwort. Erste Linie. EDIT: Ups, vielleicht habe ich nicht gespeichert? oder meine Bearbeitung wurde abgelehnt? So oder so, fügte Vincent in einer Autorelease hinzu, also yay dafür!
Eric Goldberg
1
Warum hängt meine App bei Verwendung von ARC und verbraucht viel CPU, wenn ich sie *paddingViewmit mehreren Textfeldern wiederverwendete ?
Der Muffin-Mann
3
Es ist eine schlechte Lösung, besser für Nate Flinks. Dies beinhaltet keine Auffüllung im Editiong-Modus.
Jacek Kwiecień
3
Es funktioniert nicht mit mehreren Textfeldern. Verbraucht nur so viel Speicher und stürzt später ab.
Vogelkäfig
177

Ich habe diese Kategorieimplementierung erstellt und oben in der .mDatei hinzugefügt .

@implementation UITextField (custom)
    - (CGRect)textRectForBounds:(CGRect)bounds {
        return CGRectMake(bounds.origin.x + 10, bounds.origin.y + 8,
                          bounds.size.width - 20, bounds.size.height - 16);
    }
    - (CGRect)editingRectForBounds:(CGRect)bounds {
        return [self textRectForBounds:bounds];
    }
@end

Basierend auf dem Link, den Piotr Blasiak zur Verfügung gestellt hat. Es schien einfacher zu sein, als eine ganz neue Unterklasse zu erstellen, und auch einfacher, die zusätzliche hinzuzufügen UIView. Es scheint jedoch, dass etwas fehlt, um die Auffüllung in einem Textfeld nicht steuern zu können.

Swift 4-Lösung:

class CustomTextField: UITextField {
    struct Constants {
        static let sidePadding: CGFloat = 10
        static let topPadding: CGFloat = 8
    }

    override func textRect(forBounds bounds: CGRect) -> CGRect {
        return CGRect(
            x: bounds.origin.x + Constants.sidePadding,
            y: bounds.origin.y + Constants.topPadding,
            width: bounds.size.width - Constants.sidePadding * 2,
            height: bounds.size.height - Constants.topPadding * 2
        )
    }

    override func editingRect(forBounds bounds: CGRect) -> CGRect {
        return self.textRect(forBounds: bounds)
    }
}
Nate Flink
quelle
6
Dies gibt Warnungen über Kategorien aus, die Methoden überschreiben. Siehe diese Antwort , um sie zu unterdrücken.
Pdenya
5
Ich mache das lieber nicht in einer Kategorie, aber ansonsten ist dies eine sauberere Lösung als die akzeptierte Antwort.
Bob Vork
2
Es ist besser, CGRectInset () für so etwas zu verwenden, als das eigene zu rollen. Es sieht auch etwas sauberer aus: return CGRectInset (bounds, 10, 8);
Dennis Munsie
1
@shashwat ja, Sie können jede gewünschte Polsterung angeben
Ege Akpinar
1
Als ich dies vor 4 Jahren hinzufügte, waren die Dinge mit iOS anders und ich stimme zu, dass es jetzt am besten ist, eine Unterklasse zu erstellen. Wenn Sie jedoch nur eine schnelle und schmutzige Methode zur visuellen Überprüfung Ihrer Pixelabstände wünschen, ist dies ausreichend;) Es ist also in Ordnung, wenn die Leute weiter abstimmen !!
Nate Flink
139

Eine Swift 3-Version für Xcode> 6, in der Sie den Einfügungswert in Interface Builder / Storyboard bearbeiten können.

import UIKit

@IBDesignable
class FormTextField: UITextField {

    @IBInspectable var inset: CGFloat = 0

    override func textRect(forBounds bounds: CGRect) -> CGRect {
        return bounds.insetBy(dx: inset, dy: inset)
    }

    override func editingRect(forBounds bounds: CGRect) -> CGRect {
        return textRect(forBounds: bounds)
    }

}

Geben Sie hier die Bildbeschreibung ein

Bandejapaisa
quelle
1
Ich sehe das Formulartextfeld auf meinem nicht.
Okysabeni
2
Ich musste diese Zeile hinzufügenoverride func placeholderRectForBounds(bounds: CGRect) -> CGRect { return CGRectInset(bounds, inset, inset) }
Michael
2
Diese Antwort wäre hilfreicher mit einer Erklärung oder einem Link zur Erklärung dessen, was @IBDesignableund was zu @IBInspectabletun ist, dh dieser Beitrag bei nshipster
Russell Austin
1
Wenn Sie sich auf Zubehöransichten verlassen (z. B. die Funktion zum Löschen von Schaltflächen in UITextField), return super.textRectForBounds(CGRectInset(bounds, inset, inset))wird der Versatz zu den Zubehöransichten ordnungsgemäß behandelt.
Mike Fay
@okysabeni Sie müssen auf Ihr Textfeld klicken und die Klasse in FormTextField
Gustavo Barbosa
77

Bearbeiten: Funktioniert immer noch in iOS 11.3.1

In iOS 6 myTextField.leftView = paddingView;verursacht das Problem

Dies löst das Problem

myTextField.layer.sublayerTransform = CATransform3DMakeTranslation(5, 0, 0)

Für rechtsbündiges Textfeld verwenden Sie, CATransform3DMakeTranslation(-5, 0, 0)wie vom Latenitcodierer in Kommentaren erwähnt

Inder Kumar Rathore
quelle
1
Schön, ich musste das Padding in alle Textfelder der App einfügen, ich habe eine Kategorie von UITextField erstellt und diesen Code in - (void) awakeFromNib {} eingefügt und dies hat mein Problem gelöst
Teena nath Paul
So einfach! Thx :) Ich habe eine Frage, wie ich einen einfachen Code erstellen kann, um alle UITextField zu erstellen, anstatt den Code viele Male zu schreiben.
Luai Kalkatawi
1
Bei allen anderen Kommentaren wird davon ausgegangen, dass Sie ein UITextField von links auffüllen möchten. Unterklassen sind sehr aufwändig, um eine Abstands-ID hinzuzufügen, anstatt nur einige leere Zeichen hinzuzufügen, aber diese Lösung ist DIE Lösung. Einzeiliger Zukunftssicher. Wenn Sie mit einem Textfeld arbeiten, das nach rechts ausgerichtet ist, verwenden Sie den Minuswert (-5,0,0). Danke Inder
Latenitcoder
1
Nach 4 Jahren fand ich meine eigene Antwort: D, @latenitecoder Ihr Kommentar war das, was benötigt wird. Aktualisierung der Antwort
Inder Kumar Rathore
1
Was kann ich tun, wenn ich sowohl rechts als auch links Polsterung möchte?
Mina Hanna
70

Ein guter Ansatz zum Hinzufügen von Auffüllungen zu UITextField besteht darin, eine edgeInsets-Eigenschaft zu unterordnen und hinzuzufügen. Anschließend legen Sie die edgeInsets fest und das UITextField wird entsprechend gezeichnet. Dies funktioniert auch korrekt mit einem benutzerdefinierten leftView- oder rightView-Set.

OSTextField.h

#import <UIKit/UIKit.h>

@interface OSTextField : UITextField

@property (nonatomic, assign) UIEdgeInsets edgeInsets;

@end

OSTextField.m

#import "OSTextField.h"

@implementation OSTextField

- (id)initWithFrame:(CGRect)frame{
    self = [super initWithFrame:frame];
    if (self) {
        self.edgeInsets = UIEdgeInsetsZero;
    }
    return self;
}

-(id)initWithCoder:(NSCoder *)aDecoder{
    self = [super initWithCoder:aDecoder];
    if(self){
        self.edgeInsets = UIEdgeInsetsZero;
    }
    return self;
}

- (CGRect)textRectForBounds:(CGRect)bounds {
    return [super textRectForBounds:UIEdgeInsetsInsetRect(bounds, self.edgeInsets)];
}

- (CGRect)editingRectForBounds:(CGRect)bounds {
    return [super editingRectForBounds:UIEdgeInsetsInsetRect(bounds, self.edgeInsets)];
}

@end
Brody Robertson
quelle
Dies sollte als Antwort akzeptiert werden. Es funktioniert auch für rechte und linke Ansichten.
NSPratik
25

Unterklasse UITextField einfach wie folgt:

@implementation DFTextField


- (CGRect)textRectForBounds:(CGRect)bounds
{
    return CGRectInset(bounds, 10.0f, 0);
}

- (CGRect)editingRectForBounds:(CGRect)bounds
{
    return [self textRectForBounds:bounds];
}


@end

Dies fügt eine horizontale Polsterung von 10 Punkten auf beiden Seiten hinzu.

Camsoft
quelle
21

Ziel C-Code

MyTextField.h

#import <UIKit/UIKit.h>

@interface MyTextField : UITextField

@property (nonatomic) IBInspectable CGFloat padding;

@end

MyTextField.m

#import "MyTextField.h"

IB_DESIGNABLE
@implementation MyTextField

@synthesize padding;

-(CGRect)textRectForBounds:(CGRect)bounds{
    return CGRectInset(bounds, padding, padding);
}

-(CGRect)editingRectForBounds:(CGRect)bounds{
    return [self textRectForBounds:bounds];
}

@end

Geben Sie hier die Bildbeschreibung ein

Kirit Vaghela
quelle
20
  1. Erstellen Sie ein benutzerdefiniertes Textfeld

PaddingTextField.swift

import UIKit
class PaddingTextField: UITextField {

@IBInspectable var paddingLeft: CGFloat = 0
@IBInspectable var paddingRight: CGFloat = 0

override func textRectForBounds(bounds: CGRect) -> CGRect {
    return CGRectMake(bounds.origin.x + paddingLeft, bounds.origin.y,
        bounds.size.width - paddingLeft - paddingRight, bounds.size.height);
}

override func editingRectForBounds(bounds: CGRect) -> CGRect {
    return textRectForBounds(bounds)
}}
  1. Legen Sie fest, dass Ihre Textfeldklasse PaddingTextField ist, und passen Sie das Auffüllen nach Ihren Wünschen an Geben Sie hier die Bildbeschreibung ein Geben Sie hier die Bildbeschreibung ein

  2. Geniesse es

Finale

777Q
quelle
19

Basierend auf der Antwort von Evil Trout möchten Sie möglicherweise eine Kategorie erstellen, um die Verwendung in mehreren Anwendungen zu vereinfachen.

Header-Datei:

@interface UITextField (PaddingText)

-(void) setLeftPadding:(int) paddingValue;

-(void) setRightPadding:(int) paddingValue;
@end

Implementierungsdatei:

#import "UITextField+PaddingText.h"

@implementation UITextField (PaddingText)

-(void) setLeftPadding:(int) paddingValue
{
    UIView *paddingView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, paddingValue, self.frame.size.height)];
    self.leftView = paddingView;
    self.leftViewMode = UITextFieldViewModeAlways;
}

-(void) setRightPadding:(int) paddingValue
{
    UIView *paddingView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, paddingValue, self.frame.size.height)];
    self.rightView = paddingView;
    self.rightViewMode = UITextFieldViewModeAlways;
}

@end

Anwendungsbeispiel

#import "UITextField+PaddingText.h"

[self.YourTextField setLeftPadding:20.0f];

Hoffe es hilft euch Jungs

Prost

Paulo Miguel Almeida
quelle
14

Schnelle Version:

extension UITextField {
    @IBInspectable var padding_left: CGFloat {
        get {
            LF.log("WARNING no getter for UITextField.padding_left")
            return 0
        }
        set (f) {
            layer.sublayerTransform = CATransform3DMakeTranslation(f, 0, 0)
        }
    }
}

Damit Sie in IB Wert zuweisen können

IBInspectable-Einstellung, die im Interface Builder dargestellt wird

superarts.org
quelle
IBInspectableMit dieser Option können Sie den Setter-Code zur Laufzeit anwenden. Geben Sie einfach Ihre Nummer ein Interface Builderund es wird funktionieren.
Superarts.org
Dies wird nicht funktionieren, wenn Sie haben Clear Button. Ihre Schaltfläche zum Löschen wird nicht angezeigt, wenn Sie diese Lösung anwenden.
Bhavin_m
11

Sie können die Polsterung nicht einstellen. Haben Sie stattdessen ein, UIViewdas Ihr Hintergrundbild und das UITextFieldInnere davon hat. Stellen Sie die UITextFieldBreite UIViewWidth-(paddingSize x 2)und Höhe ähnlich ein und stellen Sie sie dann auf Punkt ein paddingSize,paddingSize.

Thomas Clayson
quelle
10

Unterklasse UITextField einfach so ( Swift-Version ):

import UIKit

class CustomTextField: UITextField {

    override func textRectForBounds(bounds: CGRect) -> CGRect {
       return CGRectInset(bounds, 25.0, 0)
    }

    override func editingRectForBounds(bounds: CGRect) -> CGRect {
       return self.textRectForBounds(bounds)
    }

}

Dies fügt eine horizontale Polsterung von 25,0 Punkten auf beiden Seiten hinzu.

König-Zauberer
quelle
8

Ich habe mich auf die Lösung von Nate gestützt, aber dann habe ich festgestellt, dass dies Probleme verursacht, wenn Sie die Eigenschaften leftView / rightView verwenden. Daher ist es besser, die Implementierung des Super zu optimieren, da die Ansichten links / rechts berücksichtigt werden.

- (CGRect)textRectForBounds:(CGRect)bounds {
    CGRect ret = [super textRectForBounds:bounds];
    ret.origin.x = ret.origin.x + 5;
    ret.size.width = ret.size.width - 10;
    return ret;
}

- (CGRect)editingRectForBounds:(CGRect)bounds {
    return [self textRectForBounds:bounds];
}
Stoto
quelle
6

Aktualisierte Version für Swift 3:

@IBDesignable
class FormTextField: UITextField {

    @IBInspectable var paddingLeft: CGFloat = 0
    @IBInspectable var paddingRight: CGFloat = 0

    override func textRect(forBounds bounds: CGRect) -> CGRect {
        return CGRect(x: bounds.origin.x + paddingLeft, y: bounds.origin.y, width: bounds.size.width - paddingLeft - paddingRight, height: bounds.size.height)
    }

    override func editingRect(forBounds bounds: CGRect) -> CGRect {
        return textRect(forBounds: bounds)
    }
}
Beninho85
quelle
6

Legen Sie die Auffüllung für UITextField mit UITextBorderStyleNone: Swift fest

Basierend auf der am häufigsten gewählten Antwort von @Evil Trout habe ich in meiner ViewController-Klasse eine benutzerdefinierte Methode erstellt, wie unten gezeigt:

- (void) modifyTextField:(UITextField *)textField
{
    UIView *paddingView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 5, 20)];
    textField.leftView = paddingView;
    textField.leftViewMode = UITextFieldViewModeAlways;
    textField.rightView = paddingView;
    textField.rightViewMode = UITextFieldViewModeAlways;

    [textField setBackgroundColor:[UIColor whiteColor]];
    [textField setTextColor:[UIColor blackColor]];
}

Jetzt kann ich diese Methode im Inneren aufrufen (viewDidLoad-Methode) und alle meine TextFields an diese Methode senden und sowohl rechts als auch links Auffüllungen hinzufügen sowie Text- und Hintergrundfarben angeben, indem ich nur eine Codezeile wie folgt schreibe:

[self modifyTextField:self.firstNameTxtFld];

Dies funktionierte perfekt unter iOS 7! Ich weiß, dass das Hinzufügen zu vieler Ansichten dazu führen kann, dass diese Klasse etwas schwerer geladen werden kann. Als ich mir jedoch Sorgen über die Schwierigkeiten bei anderen Lösungen machte, war ich voreingenommener gegenüber dieser Methode und flexibler bei der Verwendung dieser Methode. ;)

Danke für den Hack "Evil Trout"! (Bogen)

Ich dachte, ich sollte das Code-Snippet dieser Antwort mit Swift aktualisieren:

Da wir mit Swift Erweiterungen für die vorhandenen Klassen schreiben können, schreiben wir es auf diese Weise.

extension UITextField {
    func addPaddingToTextField() {
        let paddingView: UIView = UIView.init(frame: CGRectMake(0, 0, 8, 20))
        self.leftView = paddingView;
        self.leftViewMode = .Always;
        self.rightView = paddingView;
        self.rightViewMode = .Always;


        self.backgroundColor = UIColor.whiteColor()
        self.textColor = UIColor.blackColor()
    }
}

Verwendungszweck:

self.firstNameTxtFld.addPaddingToTextField()

Hoffe, das wäre hilfreich für jemand anderen da draußen!
Prost!

Randika Vishman
quelle
5

So erreichen Sie dies in SWIFT

@IBOutlet weak var yourTextField: UITextField!

override func viewDidLoad() {
super.viewDidLoad()
let paddingView = UIView(frame: CGRectMake(0, 0, 10, self.yourTextField.frame.height))
yourTextField.leftView = paddingView
yourTextField.leftViewMode = UITextFieldViewMode.Always
}
}

Ressource

DrPatience
quelle
5

Swift 2.0 Version:

let paddingView: UIView = UIView(frame: CGRectMake(0, 0, 5, 20))
textField.leftView = paddingView
textField.leftViewMode = UITextFieldViewMode.Always;
Phil
quelle
4

^ Diese Vorschläge sind ideal für diejenigen, die programmgesteuert eine Schnittstelle erstellen.

Es gibt jedoch zwei LAZY EASY WAYS für diejenigen von uns, die den Xcode Interface Builder verwenden:

  • einfacher: Platzieren Sie eine UIImageView hinter einem Textfeld

  • Am einfachsten: Ändern Sie den Rahmenstil auf dem einfachen schwarzen Quadrat (zweite von links) und fügen Sie dann Ihr Bild als Hintergrundbild hinzu. Das Bild hat Vorrang vor dem Quadrat, sodass Sie immer noch die für einen normalen Bildhintergrund erforderliche Auffüllung erhalten, ohne dass das Quadrat tatsächlich gezeichnet wird.

BEARBEITEN: Sie können auch die schwarze Kugel verwenden (dritte von links, wenn Sie die UITextBox in IB auswählen). Sie funktioniert nicht mit dem ganz rechten "grafischen Kugel" -Stil.

woody121
quelle
Ihre einfachere Lösung ist in der Tat in einigen Fällen eine gültige Wahl, aber Ihre einfachste Lösung ist ein Hack, der auch nicht funktioniert, wenn die Randpixel Ihres Bildes ein variables Alpha aufweisen (ganz zu schweigen davon, dass Apple ihre Implementierung in einer zukünftigen iOS-Version ändern könnte).
jmdecombe
Ich bin nicht anderer Meinung als Sie - deshalb habe ich in Großbuchstaben "faul einfach" geschrieben. Für mich hat es bisher gut funktioniert.
Woody121
4

Wenn jemand nach einer Swift 4.0Version sucht, dann ist unten extensionArbeit. Es hat beides Leftund RightPolsterung für UITextField. Eigentlich ist es IBInspectablefür die Storyboard-Konfiguration. Sie können den Wert direkt im Interface Builder / Storyboard festlegen. Dies ist getesteter Code in Swift 4.0 und Xcode 9.0

Beachten Sie, dass Sie Right Padding leer lassen müssen , wenn Sie Clear Buttondasselbe aktivieren möchten UITextField.

import UIKit

extension UITextField {

    @IBInspectable var paddingLeft: CGFloat {
        get {
            return leftView!.frame.size.width
        }
        set {
            let paddingView = UIView(frame: CGRect(x: 0, y: 0, width: newValue, height: frame.size.height))
            leftView = paddingView
            leftViewMode = .always
        }
    }

    @IBInspectable var paddingRight: CGFloat {
        get {
            return rightView!.frame.size.width
        }
        set {
            let paddingView = UIView(frame: CGRect(x: 0, y: 0, width: newValue, height: frame.size.height))
            rightView = paddingView
            rightViewMode = .always     
        }
    }
}  
Bhavin_m
quelle
3

Der beste Weg, dies zu tun, besteht darin, einfach eine Klasse mit der Unterklasse von UITextField und in der .m-Datei zu erstellen

 #import "CustomTextField.h"
 #import <QuartzCore/QuartzCore.h>
 @implementation CustomTextField


- (id)initWithCoder:(NSCoder*)coder 
 {
  self = [super initWithCoder:coder];

  if (self) {

//self.clipsToBounds = YES;
//[self setRightViewMode:UITextFieldViewModeUnlessEditing];

self.leftView = [[UIView alloc] initWithFrame:CGRectMake(0, 0,15,46)];
self.leftViewMode=UITextFieldViewModeAlways;
   }

  return self;

 }

Gehen Sie dazu zu Ihrem Storyboard oder xib und klicken Sie auf Identity Inspector und ersetzen Sie UITextfield durch Ihre eigene Option "CustomTextField" in der Klasse.

Hinweis: Wenn Sie einfach ein Auffüllen mit automatischem Layout für das Textfeld angeben, wird Ihre Anwendung nicht ausgeführt und zeigt nur einen leeren Bildschirm an.

Anuj Kumar Rai
quelle
3

Swift 3 Version:

class CustomTextField:UITextField{

    required init?(coder aDecoder: NSCoder){
        super.init(coder: aDecoder)
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
    }

    override func textRect(forBounds bounds: CGRect) -> CGRect {
        return CGRect.init(x: bounds.origin.x + 8, y: bounds.origin.y, width: bounds.width, height: bounds.height)
    }

    override func editingRect(forBounds bounds: CGRect) -> CGRect {
        return self.textRect(forBounds:bounds)
    }
}
王怡飞
quelle
2

Die Antwort von Nate Flink ist meine Lieblingsantwort, aber vergessen Sie nicht die Ansichten rechts / links. ZB für UITextFieldUnterklasse:

override func rightViewRectForBounds(bounds: CGRect) -> CGRect {
    let rightViewBounds = super.rightViewRectForBounds(bounds)

    return CGRectMake(CGRectGetMinX(rightViewBounds) - 10, CGRectGetMinY(rightViewBounds), CGRectGetWidth(rightViewBounds), CGRectGetHeight(rightViewBounds))
}

Oben Code richtig auffüllen für rightViewvon UITextField.

Rafalkitta
quelle
2

Swift 3-Lösung

class CustomTextField: UITextField {

 override func textRect(forBounds bounds: CGRect) -> CGRect {
  return CGRect(x: bounds.origin.x + 10, y: bounds.origin.y + 8, width: bounds.size.width - 20, height: bounds.size.height - 16)
 }

 override func editingRect(forBounds bounds: CGRect) -> CGRect {
  return self.textRect(forBounds: bounds)
 }
}
Ben Sullivan
quelle
2

Hier ist ein Swift-Code zum Auffüllen in UITextfield

 func txtPaddingVw(txt:UITextField) {
     let paddingView = UIView(frame: CGRectMake(0, 0, 10, 10))
     txt.leftViewMode = .Always
     txt.leftView = paddingView
 }

und mit anrufen

self.txtPaddingVw(txtPin)
Hardik Thakkar
quelle
2

Sie können Kategorie verwenden. Stellen Sie die Polsterung auf links und rechts

UITextField + Padding.h

@interface UITextField (Padding)
@property (nonatomic, assign) CGFloat paddingValue;
@property (nonatomic, assign) CGFloat leftPadding;
@property (nonatomic, assign) CGFloat rightPadding;

//overwrite
-(CGRect)textRectForBounds:(CGRect)bounds;
-(CGRect)editingRectForBounds:(CGRect)bounds;
@end

UITextField + Padding.m

#import "UITextField+Padding.h"
#import <objc/runtime.h>

static char TAG_LeftPaddingKey;
static char TAG_RightPaddingKey;
static char TAG_Left_RightPaddingKey;

@implementation UITextField (Padding)

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation"
-(CGRect)textRectForBounds:(CGRect)bounds {

CGFloat offset_Left=0;
CGFloat offset_Right=0;
if (self.paddingValue>0) {
    offset_Left=self.paddingValue;
    offset_Right=offset_Left;
}else{
    if (self.leftPadding>0){
        offset_Left=self.leftPadding;
    }
    if (self.rightPadding>0){
        offset_Right=self.rightPadding;
    }
}

if (offset_Left>0||offset_Right>0) {
    return CGRectMake(bounds.origin.x+ offset_Left ,bounds.origin.y ,
                      bounds.size.width- (offset_Left+offset_Right), bounds.size.height-2 );
 }else{
    return bounds;
 }
}



-(CGRect)editingRectForBounds:(CGRect)bounds {
    return [self textRectForBounds:bounds];
}
#pragma clang diagnostic pop


#pragma maek -setter&&getter
- (CGFloat)paddingValue
{
    return [objc_getAssociatedObject(self,&TAG_Left_RightPaddingKey) floatValue];
}
-(void)setPaddingValue:(CGFloat)paddingValue
{
    objc_setAssociatedObject(self, &TAG_Left_RightPaddingKey, @(paddingValue), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

-(CGFloat)leftPadding
{
    return [objc_getAssociatedObject(self,&TAG_LeftPaddingKey) floatValue];
}

-(void)setLeftPadding:(CGFloat)leftPadding
{
    objc_setAssociatedObject(self, &TAG_LeftPaddingKey, @(leftPadding), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

-(CGFloat)rightPadding
{
    return [objc_getAssociatedObject(self,&TAG_RightPaddingKey) floatValue];
}

-(void)setRightPadding:(CGFloat)rightPadding
{
    objc_setAssociatedObject(self, &TAG_RightPaddingKey, @(rightPadding), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

@end

Sie können das Auffüllen wie folgt einstellen. self.phoneNumTF.paddingValue = 10.f; oder self.phoneNumTF.leftPadding = 10.f;

Rikiluo
quelle
1

@ Evil Forelle Antwort ist großartig. Ich benutze diesen Ansatz schon seit einiger Zeit. Es fehlt nur noch der "Umgang mit zahlreichen Textfeldern". Ich habe andere Ansätze ausprobiert, scheint aber nicht zu funktionieren.

Das Unterklassen von UITextField, nur um eine Polsterung hinzuzufügen, ergab für mich keinen Sinn. Also habe ich alle UITextFields durchlaufen, um die Auffüllung hinzuzufügen.

-(void) addPaddingToAllTextFields:(UIView*)view {

    for(id currentView in [view subviews]){
        if([currentView isKindOfClass:[UITextField class]]) {
            // Change value of CGRectMake to fit ur need
            [currentView setLeftView:[[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 20)]];
            [currentView setLeftViewMode:UITextFieldViewModeAlways];
        }

        if([currentView respondsToSelector:@selector(subviews)]){
            [textfieldarray addObjectsFromArray:[self addPaddingToAllTextFields:currentView]];
        }
    }
}
Kishor Kundan
quelle
Die Methode kann von [self addPaddingToAllTextFields: [self view]] aufgerufen werden.
Kishor Kundan
Da textfieldarrayes im zweiten ifBlock nicht definiert ist , habe ich dieses Snippet (danke!) Mit Erfolg verwendet, nachdem ich den Inhalt des zweiten ifdurchfor(id subSubView in [view subviews]){[self addPaddingToAllTextFields:subSubView];}
adamup
1

Brodys Lösung hat perfekt für mich funktioniert. Ich musste Seitenansichten zu einem Textfeld hinzufügen und zusätzliche Auffüllungen hinzufügen. Durch die Implementierung der benutzerdefinierten UIEdgeInsets-Eigenschaft in eine UITextField-Unterklasse ist es mir gelungen, die Aufgabe zu erfüllen. Ich werde diese neue Unterklasse in allen meinen Projekten verwenden.

Lubakis
quelle
1

Die beste Lösung, die ich bisher gefunden habe, ist eine Kategorie. So füge ich links und rechts eine 5-Punkte-Polsterung hinzu:

@implementation UITextField (Padding)

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation"
- (CGRect)textRectForBounds:(CGRect)bounds {
    return CGRectMake(bounds.origin.x + 5, bounds.origin.y,
                      bounds.size.width - 10, bounds.size.height);
}
- (CGRect)editingRectForBounds:(CGRect)bounds {
    return [self textRectForBounds:bounds];
}
#pragma clang diagnostic pop

@end

Die # Pragmas dienen nur zum Entfernen der nervigen Warnungen

Mongi Zaidi
quelle
Die Sache mit der Methodenüberladung in Kategorien ist, dass sie in AppCode als nicht verwendet markiert wird, was tatsächlich der Fall ist. Gute Idee, aber nicht sehr sicher, da es leicht entfernt werden kann, wenn Sie "Importe optimieren" ausführen (kein Problem für Xcode-Benutzer, aber wir alle kennen die eingeschränkten
codezentrierten
1
Ist es eine einfache Mistkategorie, bei der alle Textfelder in der App aufgefüllt werden?
Ben Sinclair
@Andy nein, es gilt nur, wenn Sie es importieren. Sie müssen eine Klasse UITextField + Padding erstellen und in den Viewcontroller oder die Klasse importieren, für die Sie ein Textfeld mit Padding haben
Mongi Zaidi
@ MongiZaidi: Du liegst falsch. Es wird mit der ausführbaren Datei verknüpft, ob der Import irrelevant ist.
Zsolt Szatmari
1
textField.layer.borderWidth = 3;

wird Rand hinzufügen, der als Polsterung für mich arbeitete.

Saqib Saud
quelle
0

Eine weitere Überlegung ist, dass Sie, wenn Sie mehr als eine haben, UITextFieldin der Sie Auffüllungen hinzufügen, UIViewfür jedes Textfeld eine eigene erstellen müssen, da diese nicht gemeinsam genutzt werden können.

user1686700
quelle