Forum Archive

Check if iOS device is in light or dark mode

samaklis

Is there a way to check if the iPhone, iPad is in dark or light mode? The ui.get_ui_style() seems to only be querying the Pythonista app mode.

I am looking for something that would give me access to Apple's UITraitCollection, which is inherited by the UIView but I am not sure how it can be accessed through the objc_util library if at all.

Thanks

mcriley821
import objc_util
traits=objc_util.ObjCClass('UITraitCollection').currentTraitCollection()
mode=traits.userInterfaceStyle()
if mode==2:
    print(‘Dark’)
else:
    print(‘Light’)

Try this out. It worked for me...

samaklis

@mcriley821 said:

traits=objc_util.ObjCClass('UITraitCollection').currentTraitCollection()
mode=traits.userInterfaceStyle()
if mode==2:
print(‘Dark’)
else:
print(‘Light’)

Perfect, thanks

samaklis

@mcriley821 I have a quick question. I have implemented the function you gave me in a “utility” module and it works fine when calling it from the “main” view. If I call it after loading another “sheet” view, from within that view’s code, the function returns without detecting the theme as it is set in iOS.

Any ideas why the same function would work correctly from the main view and not from other views?

Thanks

From the main view calling the check periodically:

class ThemeThread(threading.Thread):
    def __init__(self, event, views=()):
        threading.Thread.__init__(self)
        self.stopped = event
        self.views = views


    def run(self):
        while not self.stopped.wait(2.0):
            mode = utility.get_device_mode()
            print('mode for main screen: {}'.format(mode))
            if mode == 'dark':
                self.change_bg_color('black')
            else:
                self.change_bg_color('white') 

From the other module after loading the “sheet” view:


class AppConfiguration(object):

    def __init__(self):
        self.utility = Utility()
        self.config_file = 'app_configuration.json'
        self.screen = ui.load_view("screens_configuration")
        mode = self.utility.get_device_mode()
        print('mode returns: {}'.format(mode))

My utility module code:


    def get_device_mode(self):
        traits=objc_util.ObjCClass('UITraitCollection').currentTraitCollection()
        mode=traits.userInterfaceStyle()

        print('utility mode: {}'.format(mode))
        if mode==2:
            return 'dark'
        else:
            return 'light'

Console output:

utility mode: 2
utility mode: 2
mode for main screen: dark
utility mode: 2
mode for main screen: dark
utility mode: 1
mode returns: light
utility mode: 2
mode for main screen: dark
utility mode: 2
mode for main screen: dark
utility mode: 2
mode for main screen: dark
main view will close...
mcriley821

@samaklis UICurrentTraitCollection will return the traits of the most current view you’re presenting, and if I’m not mistaken, new ui views are defaulted to light mode. What you could do is set the trait collection of your presented view as the trait collection of the main view

samaklis

I realized that there is already a function that works correctly when it comes to detection the light/dark mode at any screen, built into the ui module...

In case anyone has the same problem the below does the trick:

ui.get_ui_style()