Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UITextField placeholder text is unreadable in iOS13 dark mode

UITextField has a .placeholder text property, for showing info before text has been added to the field, up until now it's always been clear and visible, but in iOS13 dark mode was introduced and now placeholder text is practically unreadable in a white UITextField (I am explicitly making it white via .backgroundColor = [UIColor whiteColor]).

My question is, what are some practical solutions to fix this throughout my project, I could manually change the placeholder color on any UITextField manually, by simply setting an attributedPlaceholder string, that may take a while, is there a way to disable dark mode settings just on UITextFields specifically but not for other elements?

like image 230
Albert Renshaw Avatar asked Oct 21 '19 01:10

Albert Renshaw


3 Answers

in swift Paste the below code to appdelegate file

if #available(iOS 13.0, *) {
            window!.overrideUserInterfaceStyle = .light
        }

It will work fine.

like image 96
Ananta Prasad Avatar answered Oct 17 '22 12:10

Ananta Prasad


I would consider not explicitly setting the text field background to white.

You can more robustly support dark and light mode by using UI Element colors described here: https://developer.apple.com/documentation/uikit/uicolor/ui_element_colors

For one of my text fields I did something like this:

if #available(iOS 13, *) {
    self.searchBarTextField.textColor = UIColor.label
    self.searchBarTextField.backgroundColor = UIColor.secondarySystemBackground
} else {
    self.searchBarTextField.backgroundColor = UIColor(white: 1.0, alpha: 1.0)
}

From the code above, now the background of your textfield will dynamically change when the user changes their light vs dark mode setting. And the text color will change with it. And by placeholder text color will be handled by OS. You could override if you needed: https://developer.apple.com/documentation/uikit/uicolor/3173134-placeholdertext

like image 37
Albert Tong Avatar answered Oct 17 '22 12:10

Albert Tong


It turns out Apple has provided a way to override this on various elements (or even your entire app's UIWindow) with the following (Objective-C):

if (@available(iOS 13.0, *)) {
    textField.overrideUserInterfaceStyle = UIUserInterfaceStyleLight;
}

I applied it to all UITextFields via swizzle, to turn it off on EVERYTHING in your project, just use this in your appDelegate didFinishLaunching method but replace textField with _window

(IMPORTANT EDIT: with the newest version of xCode _window seems to have been dropped and now app projects create something called a SceneDelegate and the overrideUserInterfaceStyle has to be applied to that somehow, but I'm new to scene delegates and don't know how they work so I can't offer much help there, to disable scenedelegate and return to traditional AppDelegate management of the UIWindow, see here: https://stackoverflow.com/a/57467270/2057171)

like image 21
Albert Renshaw Avatar answered Oct 17 '22 13:10

Albert Renshaw