1 import ABI49_0_0ExpoModulesCore 2 3 public class ScreenOrientationModule: Module, ScreenOrientationController { 4 static let didUpdateDimensionsEvent = "expoDidUpdateDimensions" 5 6 let screenOrientationRegistry = ScreenOrientationRegistry.shared 7 var shouldEmitEvents = false 8 9 public func definition() -> ModuleDefinition { 10 Name("ExpoScreenOrientation") 11 12 Events("expoDidUpdateDimensions") 13 14 AsyncFunction("lockAsync") { (orientationLock: ModuleOrientationLock) in 15 let orientationMask = orientationLock.toInterfaceOrientationMask() 16 17 guard !orientationMask.isEmpty else { 18 throw InvalidOrientationLockException() 19 } 20 21 guard orientationMask.isSupportedByDevice() else { 22 throw UnsupportedOrientationLockException(orientationLock) 23 } 24 25 screenOrientationRegistry.setMask(orientationMask, forController: self) 26 } 27 28 AsyncFunction("lockPlatformAsync") { (allowedOrientations: [ModuleOrientation]) in 29 var allowedOrientationsMask: UIInterfaceOrientationMask = [] 30 31 for allowedOrientation in allowedOrientations { 32 let orientation = allowedOrientation.toInterfaceOrientation() 33 let orientationMask = orientation.toInterfaceOrientationMask() 34 35 guard !orientationMask.isEmpty else { 36 throw InvalidOrientationLockException() 37 } 38 39 allowedOrientationsMask.insert(orientationMask) 40 } 41 42 guard allowedOrientationsMask.isSupportedByDevice() else { 43 throw UnsupportedOrientationLockException(nil) 44 } 45 46 screenOrientationRegistry.setMask(allowedOrientationsMask, forController: self) 47 } 48 49 AsyncFunction("getOrientationLockAsync") { 50 return ModuleOrientationLock.from(mask: screenOrientationRegistry.currentOrientationMask).rawValue 51 } 52 53 AsyncFunction("getPlatformOrientationLockAsync") { () -> [Int] in 54 let orientationMask = screenOrientationRegistry.currentOrientationMask 55 var allowedOrientations: [Int] = [] 56 let orientationMasks: [UIInterfaceOrientationMask] = [.portrait, .portraitUpsideDown, .landscapeLeft, .landscapeRight] 57 58 // If the particular orientation is supported, we add it to the array of allowedOrientations 59 for wrappedSingleOrientation in orientationMasks { 60 let supportedOrientationMask = orientationMask.intersection(wrappedSingleOrientation) 61 if !supportedOrientationMask.isEmpty { 62 let supportedOrientation = supportedOrientationMask.toUIInterfaceOrientation() 63 allowedOrientations.append(ModuleOrientation.from(orientation: supportedOrientation).rawValue) 64 } 65 } 66 return allowedOrientations 67 } 68 69 AsyncFunction("supportsOrientationLockAsync") { (orientationLock: ModuleOrientationLock) -> Bool in 70 let orientationMask = orientationLock.toInterfaceOrientationMask() 71 return !orientationMask.isEmpty && orientationMask.isSupportedByDevice() 72 } 73 74 AsyncFunction("getOrientationAsync") { 75 return ModuleOrientation.from(orientation: screenOrientationRegistry.currentScreenOrientation).rawValue 76 } 77 78 OnCreate { 79 screenOrientationRegistry.registerController(self) 80 } 81 82 OnDestroy { 83 screenOrientationRegistry.unregisterController(self) 84 } 85 86 OnStartObserving { 87 shouldEmitEvents = true 88 } 89 90 OnStopObserving { 91 shouldEmitEvents = false 92 } 93 } 94 95 // MARK: - ScreenOrientationController 96 97 public func screenOrientationDidChange(_ orientation: UIInterfaceOrientation) { 98 guard let currentTraitCollection = screenOrientationRegistry.currentTraitCollection, shouldEmitEvents else { 99 return 100 } 101 102 sendEvent(ScreenOrientationModule.didUpdateDimensionsEvent, [ 103 "orientationLock": ModuleOrientationLock.from(mask: screenOrientationRegistry.currentOrientationMask).rawValue, 104 "orientationInfo": [ 105 "orientation": ModuleOrientation.from(orientation: orientation).rawValue, 106 "verticalSizeClass": currentTraitCollection.verticalSizeClass, 107 "horizontalSizeClass": currentTraitCollection.horizontalSizeClass 108 ] as [String: Any] 109 ]) 110 } 111 } 112