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?

Alex Catchpole
źródło

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])
vacawama
źródło
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.

Crubio
źródło
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

jose920405
źródło
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])
Sreedeepkesav MS
źródło
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.

Tejinder
źródło
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

Krzynool
źródło
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)

Ridho Octanio
źródło
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!])
        }
    }
}
Khawar Islam
źródło
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}];
Álvaro Agüero
źródło
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!

Paul Lehn
źródło
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
    }
}
ninja_iOS
źródło
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!])
        }
    }
}
Dixit Akabari
źródło
3

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

passField.attributedPlaceholder = NSAttributedString(string: "password", attributes: [NSForegroundColorAttributeName: UIColor.white])
Asfand Shabbir
źródło
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])
Ashim Dahal
źródło
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.

David Rees
źródło
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
iOS Lifee
źródło
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])
Anindya
źródło
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])
            }
        }
    }
}
Pradip Patel
źródło
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!])
    }
}

}
Vikas Rajput
źródło
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")
Celil Bozkurt
źródło
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/

Andres Paladines
źródło
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])
Mr.Javed Multani
źródło
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];

Saleh Sultan
źródło
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;

}
Jigar Darji
źródło
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;
Sureshkumar Linganathan
źródło
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!])
                }
            } 
}
Dilip Mishra
źródło
-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)
Codewithj
źródło
-1

Dla Swift 4

txtField1.attributedPlaceholder = NSAttributedString(string: "-", attributes: [NSAttributedStringKey.foregroundColor: UIColor.white])
Arjun Dobaria
źródło
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])
Durga Ballabha Panigrahi
źródło