Zmiana koloru tekstu zastępczego za pomocą Swift


226

Mam projekt, który implementuje ciemnoniebieski UITextField, ponieważ tekst zastępczy ma domyślnie ciemnoszary kolor, ledwo mogę zrozumieć, co mówi tekst zastępczy.

Oczywiście przejrzałem ten problem, ale jeszcze nie znalazłem rozwiązania, używając języka Swift, a nie Obj-c.

Czy istnieje sposób na zmianę koloru tekstu zastępczego za UITextFieldpomocą Swift?

Odpowiedzi:


501

Możesz ustawić tekst zastępczy za pomocą przypisanego ciągu . Podaj żądany kolor dzięki attributes:

var myTextField = UITextField(frame: CGRect(x: 0, y: 0, width: 200, height: 30))
myTextField.backgroundColor = .blue
myTextField.attributedPlaceholder = NSAttributedString(string: "placeholder text",
                             attributes: [NSForegroundColorAttributeName: UIColor.yellow])

W przypadku Swift 3+ użyj:

myTextField.attributedPlaceholder = NSAttributedString(string: "placeholder text",
                             attributes: [NSAttributedStringKey.foregroundColor: UIColor.white])

W przypadku Swift 4.2 użyj:

myTextField.attributedPlaceholder = NSAttributedString(string: "placeholder text",
                             attributes: [NSAttributedString.Key.foregroundColor: UIColor.white])

iOS 11 SDK - klucz nie ma pierwszoplanowego koloru: self.emailTextField? .attortedPlaceholder = NSAttributString (ciąg: „tekst zastępczy”, atrybuty: [NSAttributStringKey.foregroundColor: UIColor.white])
Matthew Ferguson

@MatthewFerguson, właśnie próbowałem i działa. Czy masz wydaną wersję Xcode 9? Jakiego rodzaju emailTextField?
vacawama

2
@vacawama. Dzięki za wymianę. Wcześniejszy projekt, zaktualizowałem mój Xcode ze sklepu App Store - wersja 9.0 (9A235), a na koniec wymyśliłem rozwiązanie self.passwordTextField? .AttortedPlaceholder = NSAttributString (ciąg: „PASSWORD”, atrybuty: [NSForegroundColorAttributeName: UIColor.white])
Matthew Ferguson

3
dla myTextField.attributedPlaceholder = NSAttributedString(string: "placeholder text", attributes: [NSForegroundColorAttributeName: UIColor.white])
zestawu

1
Czy istnieje sposób ustawienia koloru bez ustawiania ciągu?
ScottyBlades

285

Możesz to zrobić szybko, bez dodawania wiersza kodu, za pomocą Konstruktora interfejsów.

Wybierz UITextFieldi otwórz inspektora tożsamości po prawej stronie:

wprowadź opis zdjęcia tutaj

Kliknij przycisk plus i dodaj nowy atrybut środowiska wykonawczego:

placeholderLabel.textColor (Swift 4)

_placeholderLabel.textColor (Swift 3 lub mniej)

Użyj Koloru jako typu i wybierz kolor.

Otóż ​​to.

Nie zobaczysz wyniku, dopóki ponownie nie uruchomisz aplikacji.


1
to prawda, ale jest to rodzaj włamania, ponieważ właściwość placeholderLabel.textColor jest prywatna ...
Frédéric Adda

1
czy aplikacja zostanie odrzucona, ponieważ korzystamy z prywatnej własności klasy?
firecast

2
Niestety nie działa to przynajmniej na iOS 10.
nickdnk

2
@nickdnk Nieprawda. W tej chwili przetestowałem na iOS 10.2.1 i działa. :)
Andrej

2
Dobra droga do nieoczekiwanej awarii, jeśli Apple zmieni wewnętrzną implementację.)
Vlad

127

Utwórz UITextFieldrozszerzenie w ten sposób:

extension UITextField{
   @IBInspectable var placeHolderColor: UIColor? {
        get {
            return self.placeHolderColor
        }
        set {
            self.attributedPlaceholder = NSAttributedString(string:self.placeholder != nil ? self.placeholder! : "", attributes:[NSAttributedString.Key.foregroundColor: newValue!])
        }
    }
}

I w twojej serii ujęć lub .xib. Zobaczysz

wprowadź opis zdjęcia tutaj


11
⚠️ Ostrzeżenie: To rozszerzenie spowoduje awarię programu, jeśli kiedykolwiek zdecydujesz się przeczytać właściwość placeHolderColor! Jeśli zwrócisz wartość samej obliczonej właściwości z modułu pobierającego właściwość, moduł pobierający zostanie ponownie wywołany z poziomu modułu pobierającego, co spowoduje nieskończoną rekurencję. (Patrz: stackoverflow.com/a/42334711/2062785 )
Mischa

1
Aby to naprawić i uzyskać oczekiwane zachowanie (tj. Prawidłowy kolor zastępczy), pobierz attributedStringpierwszą literę (jeśli nie jest pusta) i zwróć jej kolor tekstu, w przeciwnym razie nil.
Mischa,

dlaczego 2 kolory są pokazane w pudełku. Myślałem, że to jest tryb ciemny, ale tak nie było.
asreerama

27

W Swift 3.0 użyj

let color = UIColor.lightText
textField.attributedPlaceholder = NSAttributedString(string: textField.placeholder, attributes: [NSForegroundColorAttributeName : color])

W Siwft 5.0 + Użyj

let color = UIColor.lightText
let placeholder = textField.placeholder ?? "" //There should be a placeholder set in storyboard or elsewhere string or pass empty
textField.attributedPlaceholder = NSAttributedString(string: placeholder, attributes: [NSAttributedString.Key.foregroundColor : color])

24

Ten kod działa w Swift3:

yourTextFieldName .setValue(UIColor.init(colorLiteralRed: 80/255, green: 80/255, blue: 80/255, alpha: 1.0), forKeyPath: "_placeholderLabel.textColor")

daj mi znać, jeśli masz jakiś problem.


z jakiegoś powodu ulega awarii, gdy próbuję zrobić to dla więcej niż 1 pola tekstowego. Pierwszy działa dobrze, a następnie zawiesza się na wszystkich kolejnych polach tekstowych. Nie wiem, dlaczego, ale chciałbym móc użyć tej metody, ponieważ jest ona najłatwiejsza i najbardziej czytelna
Tommy K

Nie ma potrzeby korzystania setValuez dostępu do własności prywatnej. Użyj odpowiednich publicznych interfejsów API.
rmaddy

To najlepsza odpowiedź ... Tnx tak bardzo.
reza_khalafi

Składnia literałowa Xcode 10 / Swift 5:#colorLiteral(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)
Lal Krishna

15

Aby ustawić kolor zastępczy raz dla wszystkich UITextFieldaplikacji, możesz:

UILabel.appearanceWhenContainedInInstancesOfClasses([UITextField.self]).textColor = UIColor.redColor()

Spowoduje to ustawienie pożądanego koloru dla wszystkich TextFieldsymboli zastępczych w całej aplikacji. Ale jest dostępny tylko od iOS 9.

Nie ma metody przed iOS 9 w szybkich appearenceWhenContainedIn .... (), ale można skorzystać z jednego z rozwiązań pod warunkiem tutaj appearanceWhenContainedIn w Swift


zmieni to nie tylko kolor zastępczy, ale także kolor tekstu.
Timur Suleimanov

7

W moim przypadku używam Swift 4

Tworzę rozszerzenie dla UITextField

extension UITextField {
    func placeholderColor(color: UIColor) {
        let attributeString = [
            NSAttributedStringKey.foregroundColor: color.withAlphaComponent(0.6),
            NSAttributedStringKey.font: self.font!
            ] as [NSAttributedStringKey : Any]
        self.attributedPlaceholder = NSAttributedString(string: self.placeholder!, attributes: attributeString)
    }
}

yourField.placeholderColor (kolor: UIColor.white)


6

Xcode 9.2 Swift 4

extension UITextField{
    @IBInspectable var placeHolderColor: UIColor? {
        get {
            return self.placeHolderColor
        }
        set {
            self.attributedPlaceholder = NSAttributedString(string:self.placeholder != nil ? self.placeholder! : "", attributes:[NSAttributedStringKey.foregroundColor: newValue!])
        }
    }
}

2
To nie zadziała. Getter spowoduje nieskończoną rekurencję.
rmaddy

2
Działa to dobrze w swift 4. Zrobiłem punkt przerwania w kodzie i sprawdziłem go .. nieskończona rekurencja się nie dzieje.
R. Mohan

1
NIE UŻYWAJ TEGO. spowoduje to nieskończoną rekurencję. spróbuj: print (textField.placeHolderColor)
David Rees

5

Swift 4:

txtControl.attributedPlaceholder = NSAttributedString(string: "Placeholder String...",attributes: [NSAttributedStringKey.foregroundColor: UIColor.gray])

Cel C :

UIColor *color = [UIColor grayColor];
txtControl.attributedPlaceholder = [[NSAttributedString alloc] initWithString:@"Placeholder String..." attributes:@{NSForegroundColorAttributeName: color}];

4

Oto moja szybka implementacja dla swift 4:

extension UITextField {
    func placeholderColor(_ color: UIColor){
        var placeholderText = ""
        if self.placeholder != nil{
            placeholderText = self.placeholder!
        }
        self.attributedPlaceholder = NSAttributedString(string: placeholderText, attributes: [NSAttributedStringKey.foregroundColor : color])
    }
}

użyj jak:

streetTextField?.placeholderColor(AppColor.blueColor)

mam nadzieję, że to komuś pomoże!


Swift 4.2: self.attortedPlaceholder = NSAttributString (string: placeholderText, atrybuty: [NSAttributString.Key.foregroundColor: color])
Sean Stayns

4

Swift 3 (prawdopodobnie 2), możesz przesłonić didSet na symbol zastępczy w UITextFieldpodklasie, aby zastosować atrybut w ten sposób:

override var placeholder: String? {

    didSet {
        guard let tmpText = placeholder else {
            self.attributedPlaceholder = NSAttributedString(string: "")
            return
        }

        let textRange = NSMakeRange(0, tmpText.characters.count)
        let attributedText = NSMutableAttributedString(string: tmpText)
        attributedText.addAttribute(NSForegroundColorAttributeName , value:UIColor(white:147.0/255.0, alpha:1.0), range: textRange)

        self.attributedPlaceholder = attributedText
    }
}

4

Dla Swift

Utwórz rozszerzenie UITextField

extension UITextField{

    func setPlaceHolderColor(){
        self.attributedPlaceholder = NSAttributedString(string: self.placeholder!, attributes: [NSForegroundColorAttributeName : UIColor.white])
    }
}

Jeśli ustawiono z storyboardu.

extension UITextField{
    @IBInspectable var placeHolderColor: UIColor? {
        get {
            return self.placeHolderColor
        }
        set {
            self.attributedPlaceholder = NSAttributedString(string:self.placeholder != nil ? self.placeholder! : "", attributes:[NSAttributedString.Key.foregroundColor : newValue!])
        }
    }
}

3

W przypadku Swift 3 i 3.1 działa to doskonale:

passField.attributedPlaceholder = NSAttributedString(string: "password", attributes: [NSForegroundColorAttributeName: UIColor.white])

3

W przypadku Swift 4.0, wersji X-code 9.1 lub iOS 11 można użyć następującej składni, aby mieć inny kolor zastępczy

textField.attributedPlaceholder = NSAttributedString(string: "Placeholder Text", attributes: [NSAttributedStringKey.foregroundColor : UIColor.white])

3

Jestem zaskoczony, widząc, ile jest marnych rozwiązań.

Oto wersja, która zawsze będzie działać.

Szybki 4.2

extension UITextField{
    @IBInspectable var placeholderColor: UIColor {
        get {
            return self.attributedPlaceholder?.attribute(.foregroundColor, at: 0, effectiveRange: nil) as? UIColor ?? .lightText
        }
        set {
            self.attributedPlaceholder = NSAttributedString(string: self.placeholder ?? "", attributes: [.foregroundColor: newValue])
        }
    }
}

WSKAZÓWKA : Jeśli zmienisz tekst zastępczy po ustawieniu koloru, kolor zostanie zresetowany.


3

Po prostu napisz poniższy kod do metody didFinishLaunchingWithOptions Appdelegate użyj tego, jeśli chcesz zmienić całą aplikację napisaną w Swift 4.2

UILabel.appearance(whenContainedInInstancesOf: [UITextField.self]).textColor = UIColor.white


1

W przypadku wersji 4.2 i nowszych możesz to zrobić w następujący sposób:

textField.attributedPlaceholder = NSAttributedString(string: "Placeholder Text", attributes: [NSAttributedString.Key.foregroundColor: UIColor.white])

1

W moim przypadku wykonałem następujące czynności:

extension UITextField {
    @IBInspectable var placeHolderColor: UIColor? {
        get {
            if let color = self.attributedPlaceholder?.attribute(.foregroundColor, at: 0, effectiveRange: nil) as? UIColor {
                return color
            }
            return nil
        }
        set (setOptionalColor) {
            if let setColor = setOptionalColor {
                let string = self.placeholder ?? ""
                self.attributedPlaceholder = NSAttributedString(string: string , attributes:[NSAttributedString.Key.foregroundColor: setColor])
            }
        }
    }
}

1

Tutaj piszę wszystkie UIDesignable z UITextField. Za pomocą tego kodu można uzyskać bezpośredni dostęp do niego z Inspektora plików interfejsu użytkownika w serii ujęć

@IBDesignable
class CustomTextField: UITextField {

@IBInspectable var leftImage: UIImage? {
    didSet {
        updateView()
    }
}

@IBInspectable var leftPadding: CGFloat = 0 {
    didSet {
        updateView()
    }
}

@IBInspectable var rightImage: UIImage? {
    didSet {
        updateView()
    }
}

@IBInspectable var rightPadding: CGFloat = 0 {
    didSet {
        updateView()
    }
}

private var _isRightViewVisible: Bool = true
var isRightViewVisible: Bool {
    get {
        return _isRightViewVisible
    }
    set {
        _isRightViewVisible = newValue
        updateView()
    }
}

func updateView() {
    setLeftImage()
    setRightImage()

    // Placeholder text color
    attributedPlaceholder = NSAttributedString(string: placeholder != nil ?  placeholder! : "", attributes:[NSAttributedString.Key.foregroundColor: tintColor])
}

func setLeftImage() {
    leftViewMode = UITextField.ViewMode.always
    var view: UIView

    if let image = leftImage {
        let imageView = UIImageView(frame: CGRect(x: leftPadding, y: 0, width: 20, height: 20))
        imageView.image = image
        // Note: In order for your image to use the tint color, you have to select the image in the Assets.xcassets and change the "Render As" property to "Template Image".
        imageView.tintColor = tintColor

        var width = imageView.frame.width + leftPadding

        if borderStyle == UITextField.BorderStyle.none || borderStyle == UITextField.BorderStyle.line {
            width += 5
        }

        view = UIView(frame: CGRect(x: 0, y: 0, width: width, height: 20))
        view.addSubview(imageView)
    } else {
        view = UIView(frame: CGRect(x: 0, y: 0, width: leftPadding, height: 20))
    }

    leftView = view
}

func setRightImage() {
    rightViewMode = UITextField.ViewMode.always

    var view: UIView

    if let image = rightImage, isRightViewVisible {
        let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 20, height: 20))
        imageView.image = image
        // Note: In order for your image to use the tint color, you have to select the image in the Assets.xcassets and change the "Render As" property to "Template Image".
        imageView.tintColor = tintColor

        var width = imageView.frame.width + rightPadding

        if borderStyle == UITextField.BorderStyle.none || borderStyle == UITextField.BorderStyle.line {
            width += 5
        }

        view = UIView(frame: CGRect(x: 0, y: 0, width: width, height: 20))
        view.addSubview(imageView)

    } else {
        view = UIView(frame: CGRect(x: 0, y: 0, width: rightPadding, height: 20))
    }

    rightView = view
}


@IBInspectable public var borderColor: UIColor = UIColor.clear {
    didSet {
        layer.borderColor = borderColor.cgColor
    }
}

@IBInspectable public var borderWidth: CGFloat = 0 {
    didSet {
        layer.borderWidth = borderWidth
    }
}

@IBInspectable public var cornerRadius: CGFloat = 0 {
    didSet {
        layer.cornerRadius = cornerRadius
    }
}
@IBInspectable public var bottomBorder: CGFloat = 0 {
    didSet {
       borderStyle = .none
        layer.backgroundColor = UIColor.white.cgColor

        layer.masksToBounds = false
     //   layer.shadowColor = UIColor.gray.cgColor
        layer.shadowOffset = CGSize(width: 0.0, height: 1.0)
        layer.shadowOpacity = 1.0
        layer.shadowRadius = 0.0
    }
}
@IBInspectable public var bottomBorderColor : UIColor = UIColor.clear {
    didSet {

        layer.shadowColor = bottomBorderColor.cgColor
        layer.shadowOffset = CGSize(width: 0.0, height: 1.0)
        layer.shadowOpacity = 1.0
        layer.shadowRadius = 0.0
    }
}
/// Sets the placeholder color
@IBInspectable var placeHolderColor: UIColor? {
    get {
        return self.placeHolderColor
    }
    set {
        self.attributedPlaceholder = NSAttributedString(string:self.placeholder != nil ? self.placeholder! : "", attributes:[NSAttributedString.Key.foregroundColor: newValue!])
    }
}

}

0

Dla Swift

func setPlaceholderColor(textField: UITextField, placeholderText: String) {
    textField.attributedPlaceholder = NSAttributedString(string: placeholderText, attributes: [NSForegroundColorAttributeName: UIColor.pelorBlack])
}

Możesz tego użyć;

self.setPlaceholderColor(textField: self.emailTextField, placeholderText: "E-Mail/Username")

0

Chodzi o spersonalizowanie pola tekstowego, ale w każdym razie podzielę się tym kodem z innej strony i sprawię, że będzie trochę lepiej:

import UIKit
extension UITextField {
func setBottomLine(borderColor: UIColor, fontColor: UIColor, placeHolderColor:UIColor, placeHolder: String) {
    self.borderStyle = UITextBorderStyle.none
    self.backgroundColor = UIColor.clear
    let borderLine = UIView()
    let height = 1.0
    borderLine.frame = CGRect(x: 0, y: Double(self.frame.height) - height, width: Double(self.frame.width), height: height)
    self.textColor = fontColor
    borderLine.backgroundColor = borderColor
    self.addSubview(borderLine)
    self.attributedPlaceholder = NSAttributedString(
        string: placeHolder,
        attributes: [NSAttributedStringKey.foregroundColor: placeHolderColor]
    )
  }
}

I możesz użyć tego w następujący sposób:

self.textField.setBottomLine(borderColor: lineColor, fontColor: fontColor, placeHolderColor: placeHolderColor, placeHolder: placeHolder)

Wiedząc, że masz UITextFieldpołączenie z ViewController.

Źródło: http://codepany.com/blog/swift-3-custom-uitextfield-with-single-line-input/


0

wprowadź opis zdjęcia tutaj

Dla celu C :

UIColor *color = [UIColor colorWithRed:0.44 green:0.44 blue:0.44 alpha:1.0];
 emailTextField.attributedPlaceholder = [[NSAttributedString alloc] initWithString:@"Friend's Email" attributes:@{NSForegroundColorAttributeName: color}];

Dla Swift :

emailTextField.attributedPlaceholder = NSAttributedString(string: "Friend's Email",
                             attributes: [NSAttributedString.Key.foregroundColor: UIColor.white])

0

Kod C celu zmiany koloru tekstu zastępczego.

Najpierw zaimportuj tę klasę objc / runtime -

#import <objc/runtime.h>

następnie zastąp nazwę pola tekstowego -

Ivar ivar =  class_getInstanceVariable([UITextField class], "_placeholderLabel");
UILabel *placeholderLabel = object_getIvar(YourTxtField, ivar);
placeholderLabel.textColor = [UIColor whiteColor];


0

dla iOS13

+(void)ChangeplaceholderColor :(UITextField *)TxtFld andColor:(UIColor*)color { 
    NSMutableAttributedString *placeholderAttributedString = [[NSMutableAttributedString alloc] initWithAttributedString:TxtFld.attributedPlaceholder];
       [placeholderAttributedString addAttribute:NSForegroundColorAttributeName value:color range:NSMakeRange(0, [placeholderAttributedString length])];
       TxtFld.attributedPlaceholder = placeholderAttributedString;

}

0

Użyj tego w Swift,

 let placeHolderText = textField.placeholder ?? ""
 let str = NSAttributedString(string:placeHolderText!, attributes: [NSAttributedString.Key.foregroundColor :UIColor.lightGray])
 textField.attributedPlaceholder = str

W celu C

NSString *placeHolder = [textField.placeholder length]>0 ? textField.placeholder: @"";
NSAttributedString *str = [[NSAttributedString alloc] initWithString:placeHolder attributes:@{ NSForegroundColorAttributeName : [UIColor lightGrayColor] }];
textField.attributedPlaceholder = str;

0
    extension UITextField{
            @IBInspectable var placeHolderColor: UIColor? {
                get {
                    return self.placeHolderColor
                }
                set {
                    self.attributedPlaceholder = NSAttributedString(string:self.placeholder != nil ?
        self.placeholder! : "",
        attributes:[NSAttributedString.Key.foregroundColor : newValue!])
                }
            } 
}

-1

Użyj tego, aby dodać przypisany symbol zastępczy:

let attributes : [String : Any]  = [ NSForegroundColorAttributeName: UIColor.lightGray,
                                     NSFontAttributeName : UIFont(name: "Helvetica Neue Light Italic", size: 12.0)!
                                   ]
x_textfield.attributedPlaceholder = NSAttributedString(string: "Placeholder Text", attributes:attributes)

-1

Dla Swift 4

txtField1.attributedPlaceholder = NSAttributedString(string: "-", attributes: [NSAttributedStringKey.foregroundColor: UIColor.white])

1
Jest to duplikat kilku wcześniejszych odpowiedzi. Nie trzeba publikować duplikatów odpowiedzi.
rmaddy

-2
yourTextfield.attributedPlaceholder = NSAttributedString(string: "your placeholder text",attributes: [NSForegroundColorAttributeName: UIColor.white])
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.