UITextField placeholder text is unreadable in iOS13 dark mode

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)


in swift Paste the below code to appdelegate file

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

It will work fine.


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