facebook / react-native

A framework for building native applications using React

Home Page:https://reactnative.dev

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[iOS 13 beta] DatePickerIOS is invisible having dark mode enabled

ffraenz opened this issue · comments

React Native version: 0.60.5

This may be relevant to #25181 discussing Xcode 11 and iOS 13 Beta.

Steps To Reproduce

  1. Run react-native init ExampleDatePicker to create a new project.
  2. Add <DatePickerIOS date={new Date()} /> to the bottom of the scroll view in App.js.
  3. Run app on iOS 13 (simulator or test device) having dark mode enabled.
  4. The date picker is interactive (you hear the ticking noise when dragging the wheels) but it appears transparent – you can't see it.

Describe what you expected to happen:
I expected to see the date picker.

This is what it looks like on iOS 13 with dark mode disabled:

Screenshot

…on iOS 13 with dark mode enabled:

Screenshot

For future reference: You can enforce 'light mode' on the React root view by adding following line to the AppDelegate.m file. This also brings back the date picker although dark mode is enabled on the system.

rootView.overrideUserInterfaceStyle = UIUserInterfaceStyleLight;

@ffraenz Unfortunately this solution not working :(

@piotrfalba it works no worry.

Ensure you added in your appDelegate.m:

// force light theme to avoid white text in white background TextInput
  if (@available(iOS 13.0, *)) {
    rootView.overrideUserInterfaceStyle = UIUserInterfaceStyleLight;
  }

And force (not needed but anyway) restart RN server:

npm start -- --reset-cache

@ffraenz DatePickerIOS is deprecated. Use https://github.com/react-native-community/react-native-datetimepicker
If you will have same results, open issue there please.

hi, i have the same problem.... i use expo 35 and with "userInterfaceStyle": "light", stay trasparent...
there is any solution?

I managed to make it work by setting to selft.window instead of rootView.

I added the following code in AppDelegate.m

if (@available(iOS 13, *)) {
    self.window.overrideUserInterfaceStyle = UIUserInterfaceStyleLight;
}

return YES;

I tried both the self.window and rootView overrides and neither worked for me. I finally discovered a workaround that works in 13.1.2.
Add this to your plist file:

<key>UIUserInterfaceStyle</key>
<string>Light</string>

How to fix in EXPO.

I don't use Expo, but one of the SO answers I found did have a reference to this section of the docs that allows you to insert items into the plist.
https://docs.expo.io/versions/latest/distribution/app-stores/#system-permissions-dialogs-on-ios

Hi @leelandclay , I applied that but its not working. Still Date is not visible in IOS 13 in Dark mode -> ON

I don't know enough about Expo to help. Did you try going to their boards/asking on Stack Overflow and such?

Dear @hiren0412 , if you are using Expo as me, as far as I know, you have to detect current theme and change the backgroundColor of the View wrapping DatePickerIos. Since you have to use Appearence module to detect current theme, you should use Expo SDK v35. I solved this issue like that.
However, if a user changes theme while using app, this issue still remains. It is likely that Appearence modules event handler doesn't run correctly yet.

I can't get any of these options to work with Expo v35 and https://github.com/xgfe/react-native-datepicker

I tried both the self.window and rootView overrides and neither worked for me. I finally discovered a workaround that works in 13.1.2.
Add this to your plist file:

<key>UIUserInterfaceStyle</key>
<string>Light</string>

Best solution ever

None of these solutions are working for me.

For those that are still having problems.

First, check to see if manually setting Light Mode on the device fixes the problem. If it doesn't, then there is a different problem than what has been worked out here and none of these fixes will work.

Next, Are you using Expo???? If you're using Expo, then these fixes will not work because they don't seem to allow the addition of the UIUserInterfaceStyle plist entry. Considering it's new, I'm guessing it will become available in a future release of Expo. I would recommend going to Expo instead of react-native...there's nothing that can be done on this side.

If you're not using Expo and still having the problems, please provide details as far as what device and OS build you're using.

Fixed this one in Expo with following:

customStyles={{
    datePicker: {
        backgroundColor: 'black'
    }
}}

Although this makes the datepicker background black, at least it's functional and text fields are visible.

Regarding this suggested solution:

<key>UIUserInterfaceStyle</key>
<string>Light</string>

Has anyone faced the app being rejected due to invalid Info.plist? Or has it been fixed on 13.1.2?

There's an ongoing conversation here:

https://stackoverflow.com/questions/56537855/is-it-possible-to-opt-out-of-dark-mode-on-ios-13

I've submitted 2 updates to my app with this in the plist, latest one was on Oct 11th. I haven't had any problems with getting it approved.

We've got an issue with an iPhone X user which is using Dark Mode:

image

Is this the same issue?

React Native 0.59.10

@henrymoulton yes this is the same issue! 😉

Thanks @jittuu for your solution, it's the one that worked for me! 🙂

However, this solution didn't work for me, @Noitham my app has been refused today because of this but accepted with @jittuu 's solution. It works locally but not when uploading on AppStore Connect… 😞

I tried both the self.window and rootView overrides and neither worked for me. I finally discovered a workaround that works in 13.1.2.
Add this to your plist file:

<key>UIUserInterfaceStyle</key>
<string>Light</string>

I tried this solution and it worked perfectly to stop this issue but caused other side effects. On the pages in our app that are supposed to have a white status bar and dark status bar content, the content is forced to light and thus disappears.

I have solved it without making changes to appDelegate.m

Pure React Native solution is to use https://github.com/expo/react-native-appearance and props
datePickerCon: { backgroundColor: '#000' },

So assuming your customers have both light and dark color schemes, we use the code as follows:

import { Appearance } from 'react-native-appearance'; // Import module dependency
...

// Skip code to component render function
render() {
...
// Check color scheme and set proper BG
const colorScheme = Appearance.getColorScheme();
let bgColor;
if(colorScheme === 'dark'){
  bgColor = '#000';
}else{
  bgColor = '#fff';
}
...
// Skip code till return function
return (
....
// The place where you render DatePicker
<DatePicker
   customStyles={{
    // This prop is responsible for DatePicker background
    datePickerCon: {
      backgroundColor: bgColor
     },...```

**** For those using Expo ****
can simply add the following to your code to fix since there is a "isDarkModeEnabled" prop in the component. Solution does not affect Android

run 'expo install react-native-appearance' in CLI

import { Appearance } from 'react-native-appearance';
import DateTimePicker from "react-native-modal-datetime-picker";

render() {
let colorScheme = Appearance.getColorScheme();
let darkMode = false
if (colorScheme === 'dark') {
// render some dark thing
darkMode = true
}

    return (
          <DateTimePicker 
             ...
             isDarkModeEnabled={darkMode}
             mode={'date'} // or can use 'time'
           />
    )

}

This issue will be fixed on SDK36, any advice from expo guys? Probably setting from app.json (userInterfaceStyle) must be respected, thanks !!!

I tried both the self.window and rootView overrides and neither worked for me. I finally discovered a workaround that works in 13.1.2.
Add this to your plist file:

<key>UIUserInterfaceStyle</key>
<string>Light</string>

This solves my issue. Actually the text is not invisible, it's just a white font on a white background (or black font on a black background)

@leelandclay worked perfectly in my case was with expo
added "UIUserInterfaceStyle": "Light" to app.json's infoPlist

@devmateuss which version of expo are you using? SDK36? did you run in client or standalone mode?

@devmateuss Using expo, tried this in app.json file unable to make it work.
"infoPlist": {
"UIUserInterfaceStyle": "Light"
},

Appreciate any help!

@guptanisha im on the same boat, I will try to use the plist feature running expo on standalone mode

<DatePicker
....
customStyles={{
datePicker:{backgroundColor: '#222'}
}}
/>

@Fokus969 Thanks for the prompt response. The above solution works for me as well but looking for 'Opt-out and disable Dark Mode'.

@outaTiME where do u find the 'InfoPlist.js' file in the standalone project using expo. Do u use app.json 'ios' property?

thanks for the response!

@outaTiME version 35. the error was appearing in production mode with IOS in version 13

I have solved it without making changes to appDelegate.m

Pure React Native solution is to use https://github.com/expo/react-native-appearance and props
datePickerCon: { backgroundColor: '#000' },

So assuming your customers have both light and dark color schemes, we use the code as follows:

import { Appearance } from 'react-native-appearance'; // Import module dependency
...

// Skip code to component render function
render() {
...
// Check color scheme and set proper BG
const colorScheme = Appearance.getColorScheme();
let bgColor;
if(colorScheme === 'dark'){
  bgColor = '#000';
}else{
  bgColor = '#fff';
}
...
// Skip code till return function
return (
....
// The place where you render DatePicker
<DatePicker
   customStyles={{
    // This prop is responsible for DatePicker background
    datePickerCon: {
      backgroundColor: bgColor
     },...```

@IgorGanapolsky this works perfectly for ios, but throws below error on android:
"null is not an object (evaluating '_NativeAppearance.NativeAppearance.initialPreferences')"

Is Android not been affected?

@guptanisha Haven't touched React Native in several years :). I found the tooling too complex for new developers to come on board. I am putting my bets on Kotlin Multiplatform & Flutter 😉

I have solved it without making changes to appDelegate.m

Pure React Native solution is to use https://github.com/expo/react-native-appearance and props
datePickerCon: { backgroundColor: '#000' },

So assuming your customers have both light and dark color schemes, we use the code as follows:

import { Appearance } from 'react-native-appearance'; // Import module dependency
...

// Skip code to component render function
render() {
...
// Check color scheme and set proper BG
const colorScheme = Appearance.getColorScheme();
let bgColor;
if(colorScheme === 'dark'){
  bgColor = '#000';
}else{
  bgColor = '#fff';
}
...
// Skip code till return function
return (
....
// The place where you render DatePicker
<DatePicker
   customStyles={{
    // This prop is responsible for DatePicker background
    datePickerCon: {
      backgroundColor: bgColor
     },...```

@IgorUsoltsev this works perfectly for ios, but throws below error on android:
"null is not an object (evaluating '_NativeAppearance.NativeAppearance.initialPreferences')"

Is Android not been affected?

@guptanisha Im using into app.json, you could define it in the following way:

{
  "expo": {
    "ios": {
      "infoPlist": {
        "UIUserInterfaceStyle": "Light"
      },
    },
  }
}

But doesn't work to my running into expo client, i don try in standalone mode (expo build:ios).

@devmateuss When you say production mode what it means ? standalone mode ? using the command expo build:ios? i try to update the infoPlist from app.json and in client mode doesnt work, but it think it could be work on standalone.

@outaTiME I have tried in a standalone app. It works 👍

Thanks!

@guptanisha Alternatively you can try the following in standalone mode too (i dont try yet with Expo SDK36):

{
  "expo": {
    "ios": {
      "userInterfaceStyle": "light"
    },
  }
}

I tried both the self.window and rootView overrides and neither worked for me. I finally discovered a workaround that works in 13.1.2.
Add this to your plist file:

<key>UIUserInterfaceStyle</key>
<string>Light</string>

Amazing, thanks!

For the people who still have status bar in white. Make sure your UIViewControllerBasedStatusBarAppearance is true, not false. For some reason it was false on mine by default. It's in Info.plist

I have solved it without making changes to appDelegate.m
Pure React Native solution is to use https://github.com/expo/react-native-appearance and props
datePickerCon: { backgroundColor: '#000' },
So assuming your customers have both light and dark color schemes, we use the code as follows:

import { Appearance } from 'react-native-appearance'; // Import module dependency
...

// Skip code to component render function
render() {
...
// Check color scheme and set proper BG
const colorScheme = Appearance.getColorScheme();
let bgColor;
if(colorScheme === 'dark'){
  bgColor = '#000';
}else{
  bgColor = '#fff';
}
...
// Skip code till return function
return (
....
// The place where you render DatePicker
<DatePicker
   customStyles={{
    // This prop is responsible for DatePicker background
    datePickerCon: {
      backgroundColor: bgColor
     },...```

@IgorUsoltsev this works perfectly for ios, but throws below error on android:
"null is not an object (evaluating '_NativeAppearance.NativeAppearance.initialPreferences')"

Is Android not been affected?

@guptanisha I coudn't make it work on Expo Android. I had to eject Expo from my RN project anyways so it was not a blocker for me.

My advise is have maybe separate files/scenes/components to include for iOS/Android. Where Android will be free of the this code.

@IgorUsoltsev Another option instead of duplicating code, you could wrap your code in an if(Platform.os === 'ios') {} block.

@IgorUsoltsev Another option instead of duplicating code, you could wrap your code in an if(Platform.os === 'ios') {} block.

the problem is I had to use colorScheme from Appearance, not Platform.OS

I have solved it without making changes to appDelegate.m
Pure React Native solution is to use https://github.com/expo/react-native-appearance and props
datePickerCon: { backgroundColor: '#000' },
So assuming your customers have both light and dark color schemes, we use the code as follows:

import { Appearance } from 'react-native-appearance'; // Import module dependency
...

// Skip code to component render function
render() {
...
// Check color scheme and set proper BG
const colorScheme = Appearance.getColorScheme();
let bgColor;
if(colorScheme === 'dark'){
  bgColor = '#000';
}else{
  bgColor = '#fff';
}
...
// Skip code till return function
return (
....
// The place where you render DatePicker
<DatePicker
   customStyles={{
    // This prop is responsible for DatePicker background
    datePickerCon: {
      backgroundColor: bgColor
     },...```

@IgorUsoltsev this works perfectly for ios, but throws below error on android:
"null is not an object (evaluating '_NativeAppearance.NativeAppearance.initialPreferences')"
Is Android not been affected?

@guptanisha I coudn't make it work on Expo Android. I had to eject Expo from my RN project anyways so it was not a blocker for me.

My advise is have maybe separate files/scenes/components to include for iOS/Android. Where Android will be free of the this code.

This is works good

Maybe it's too obvious but if some of you, like me, had DatePicker inside and outside a modal you should use 2 of the proposed solutions here, for "normal" DatePicker @jittuu's solution and for inside modal's DatePicker @leelandclay's solution.

commented

Hey there, it looks like there has been no activity on this issue recently. Has the issue been fixed, or does it still require the community's attention? This issue may be closed if no further activity occurs. You may also label this issue as a "Discussion" or add it to the "Backlog" and I will leave it open. Thank you for your contributions.

commented

Closing this issue after a prolonged period of inactivity. If this issue is still present in the latest release, please feel free to create a new issue with up-to-date information.