Skip to content

Instantly share code, notes, and snippets.

@akshayaurora
Last active April 5, 2023 16:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save akshayaurora/fca9884cc85b2660b9b4ea6c9a5fa7de to your computer and use it in GitHub Desktop.
Save akshayaurora/fca9884cc85b2660b9b4ea6c9a5fa7de to your computer and use it in GitHub Desktop.
kivy kivy-ios iOS Listen for orientation changes and adjust for safe_areas/notch
import ios
from pyobjus import autoclass
UIDevice = autoclass('UIDevice')
CurrentDevice = UIDevice.currentDevice()
Logger.info(f'WaverianApp: iOs device name : {CurrentDevice.name.cString()}')
UIApplication = autoclass('UIApplication')
sharedApplication = UIApplication.sharedApplication()
NotchDetector = autoclass("NotchDetector").alloc().init()
def device_has_notch():
if platform != 'ios':
return False
safe_areas = ios.get_safe_area()
safe_areas = [safe_areas[x] for x in safe_areas.keys() if safe_areas[x]]
Logger.debug(f'App: iOS: Safe Srea:{safe_areas} {sharedApplication.statusBarOrientation}')
has_notch = bool(NotchDetector.hasTopNotch())
has_notch = bool(has_notch or safe_areas)
Logger.debug(f'App: Device has notch : {has_notch}')
return has_notch
''' Listen and respond to ios orientation changes
'''
from kivy.app import App
from kivy.clock import mainthread
import ios
from pyobjus import autoclass, selector, protocol
from pyobjus.protocols import protocols
from kivy.logger import Logger
from utils import device_has_notch
UIDevice = autoclass('UIDevice')
CurrentDevice = UIDevice.currentDevice()
NSNotificationCenter = autoclass('NSNotificationCenter')
protocols["OrientationDelegates"] = {
'OrientationChanged': ('v16@0:4@8', "v32@0:8@16")}
class iOSOrientationResponder(object):
'''
'''
def __init__(self, *args, **kwargs):
super(iOSOrientationResponder, self).__init__(*args, **kwargs)
self.device_name = (str(CurrentDevice.name.cString())[2:-1])
CurrentDevice.beginGeneratingDeviceOrientationNotifications()
NSNotificationCenter.defaultCenter().addObserver_selector_name_object_(
self,
selector("OrientationChanged"),
"UIDeviceOrientationDidChangeNotification",
CurrentDevice)
def stop_listening(self):
CurrentDevice.stopGeneratingDeviceOrientationNotifications()
@protocol('OrientationDelegates')
def OrientationChanged(self, notification):
self._adjust_for_notch({
1: 0,
4: 90,
2: 180,
3: 270,
5: 360,#flat
}[notification.object().orientation]
)
@mainthread
def _adjust_for_notch(self, rotation):
Logger.debug(f'App: ios Device: {self.device_name} Orientation: {rotation}')
if rotation == 5:
# do nothing when phone is flat
return
app = App.get_running_app()
# adjust for Notch
has_notch = device_has_notch()
app.root.rotation = rotation
if has_notch:
if self.device_name.lower().startswith('ipad'):
if rotation in (0, 180):
app.root.ids.top_bar.ids.top_spacing.height = '18dp'
app.root.ids.top_bar.height = '54dp'
elif rotation in (90, 270):
app.root.ids.top_bar.ids.top_spacing.height = '25dp'
app.root.ids.top_bar.height = '64dp'
app.root.ids.fl_bottom_left.width = 0
return
# non ipads
app.root.ids.bottom_bar.account_for_notch = rotation in (0, 90)
app.root.ids.top_bar.account_for_notch = rotation == 0
orientation_responder = iOSOrientationResponder()
@akshayaurora
Copy link
Author

self._adjust_for_notch(rotation, safeareas) would be the function you call to get adjust your UI according to the safe areas and current rotation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment