444 Stimmen

Texteinschub für UITextField?

Ich würde gerne die Text eines UITextField .

Ist dies möglich?

1 Stimmen

1voto

Sie könnten diese Lösung benötigen, die auch leftView und rightView unterstützt.

class InsettedTextField: UITextField {

    private let textInset: UIEdgeInsets

    var rightViewInset: CGRect {
        rightView.flatMap { $0.frame } ?? .zero
    }

    var leftViewInset: CGRect {
        leftView.flatMap { $0.frame } ?? .zero
    }

    /// Init the text field with insets.
    init(textInset: UIEdgeInsets) {
        self.textInset = textInset
        super.init(frame: .zero)
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func textRect(forBounds bounds: CGRect) -> CGRect {
        bounds
            .inset(by: textInset)
            .inset(by: UIEdgeInsets(top: 0, left: leftViewInset.width, bottom: 0, right: rightViewInset.width))
    }

    override func placeholderRect(forBounds bounds: CGRect) -> CGRect {
        bounds
            .inset(by: textInset)
            .inset(by: UIEdgeInsets(top: 0, left: leftViewInset.width, bottom: 0, right: rightViewInset.width))
    }

    override func editingRect(forBounds bounds: CGRect) -> CGRect {
        bounds
            .inset(by: textInset)
            .inset(by: UIEdgeInsets(top: 0, left: leftViewInset.width, bottom: 0, right: rightViewInset.width))
    }
}

1voto

rmooney Punkte 5865

Hier ist eine umfassende Swift-Antwort, die eine leftView (benutzerdefiniertes Symbol) und eine benutzerdefinierte Schaltfläche "Clear" enthält, die beide in Interface Builder mit anpassbaren Einschüben festgelegt wurden.

import UIKit

@IBDesignable
class InsetTextField: UITextField {
@IBInspectable var leftInset:CGFloat = 0
@IBInspectable var rightInset:CGFloat = 0
@IBInspectable var icon:UIImage? { didSet {
    let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 16, height: 16))
    imageView.image = icon
    self.leftView = imageView
    self.leftViewMode = .Always
} }

@IBInspectable var clearButton:UIImage? { didSet {
    let button = UIButton(type: .Custom)
    button.setImage(clearButton, forState: .Normal)
    button.addTarget(self, action: "clear", forControlEvents: UIControlEvents.TouchUpInside)
    button.frame = CGRect(x: 0, y: 0, width: 18, height: 18)
    self.rightView = button
    self.rightViewMode = .WhileEditing
} }

func clear() {
    self.text = ""
}

override func leftViewRectForBounds(bounds: CGRect) -> CGRect {
    var height:CGFloat = 0
    var width:CGFloat = 0
    if let leftView = self.leftView {
        height = leftView.bounds.height
        width = leftView.bounds.width
    }

    return CGRect(x: leftInset, y: bounds.height/2 - height/2, width: width, height: height)
}

override func rightViewRectForBounds(bounds: CGRect) -> CGRect {
    var height:CGFloat = 0
    var width:CGFloat = 0
    if let rightView = self.rightView {
        height = rightView.bounds.height
        width = rightView.bounds.width
    }

    return CGRect(x: bounds.width - width - rightInset, y: bounds.height/2 - height/2, width: width, height: height)
}

}

1voto

Quxflux Punkte 2926

Eine weitere Lösung, bei der keine Unterklassenbildung erforderlich ist:

UITextField *txtField = [UITextField new];
txtField.borderStyle = UITextBorderStyleRoundedRect;

// grab BG layer
CALayer *bgLayer = txtField.layer.sublayers.lastObject;
bgLayer.opacity = 0.f;

// add new bg view
UIView *bgView = [UIView new];
bgView.backgroundColor = [UIColor whiteColor];
bgView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
bgView.userInteractionEnabled = NO;

[txtField addSubview: bgView];
[txtField sendSubviewToBack: bgView];

Original UITextField Fixed UITextField

Getestet mit iOS 7 und iOS 8. Beide funktionieren. Immer noch könnte es die Chance von Apple ändern die UITextField's Layer-Hierarchie vermasseln Dinge schlecht sein.

1voto

Adam Waite Punkte 19683

Normalerweise versuche ich, Unterklassen zu vermeiden, aber dies funktioniert, wenn Sie bereits haben:

// add a property 
@property (nonatomic) UIEdgeInsets edgeInsets;

// and override:

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

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

0 Stimmen

Gibt es einen Grund, warum Sie die Unterklassenbildung vermeiden? Es est ein gültiges Gestaltungsparadigma.

0voto

Mann Punkte 5437

Wenn Sie nur den oberen und linken Einzug ändern wollen, dann

// Platzhalterposition

- (CGRect)textRectForBounds:(CGRect)bounds {

CGRect frame = bounds;
frame.origin.y = 3;
 frame.origin.x = 5;
bounds = frame;
return CGRectInset( bounds , 0 , 0 );
}

// Textposition

- (CGRect)editingRectForBounds:(CGRect)bounds {

CGRect frame = bounds;
frame.origin.y = 3;
 frame.origin.x = 5;
bounds = frame;
return CGRectInset( bounds , 0 , 0 );
}

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