expo-screen-orientation 6.0.1 → 6.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/android/build.gradle +2 -2
- package/ios/ScreenOrientationAppDelegate.swift +1 -0
- package/ios/ScreenOrientationModule.swift +8 -23
- package/ios/ScreenOrientationReactDelegateHandler.swift +1 -0
- package/ios/ScreenOrientationRegistry.swift +23 -25
- package/ios/ScreenOrientationUtilities.swift +15 -0
- package/ios/ScreenOrientationViewController.swift +41 -8
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,18 @@
|
|
|
10
10
|
|
|
11
11
|
### 💡 Others
|
|
12
12
|
|
|
13
|
+
## 6.0.3 — 2023-07-12
|
|
14
|
+
|
|
15
|
+
### 🐛 Bug fixes
|
|
16
|
+
|
|
17
|
+
- [iOS] When config plugin is not configured the initial orientation is now based on values in `Info.plist` instead of being set to portrait. ([#23456](https://github.com/expo/expo/pull/23456) by [@behenate](https://github.com/behenate))
|
|
18
|
+
|
|
19
|
+
## 6.0.2 — 2023-07-04
|
|
20
|
+
|
|
21
|
+
### 💡 Others
|
|
22
|
+
|
|
23
|
+
- [iOS] Refactor the singleton class to work properly in versioned code in Expo Go. ([#23228](https://github.com/expo/expo/pull/23228) by [@tsapeta](https://github.com/tsapeta))
|
|
24
|
+
|
|
13
25
|
## 6.0.1 — 2023-06-23
|
|
14
26
|
|
|
15
27
|
### 🐛 Bug fixes
|
package/android/build.gradle
CHANGED
|
@@ -3,7 +3,7 @@ apply plugin: 'kotlin-android'
|
|
|
3
3
|
apply plugin: 'maven-publish'
|
|
4
4
|
|
|
5
5
|
group = 'host.exp.exponent'
|
|
6
|
-
version = '6.0.
|
|
6
|
+
version = '6.0.3'
|
|
7
7
|
|
|
8
8
|
buildscript {
|
|
9
9
|
def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
|
|
@@ -67,7 +67,7 @@ android {
|
|
|
67
67
|
minSdkVersion safeExtGet("minSdkVersion", 21)
|
|
68
68
|
targetSdkVersion safeExtGet("targetSdkVersion", 33)
|
|
69
69
|
versionCode 7
|
|
70
|
-
versionName '6.0.
|
|
70
|
+
versionName '6.0.3'
|
|
71
71
|
}
|
|
72
72
|
lintOptions {
|
|
73
73
|
abortOnError false
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import ExpoModulesCore
|
|
4
4
|
|
|
5
|
+
@objc(EXScreenOrientationAppDelegate)
|
|
5
6
|
public class ScreenOrientationAppDelegate: ExpoAppDelegateSubscriber {
|
|
6
7
|
public func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
|
|
7
8
|
ScreenOrientationRegistry.shared.updateCurrentScreenOrientation()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import ExpoModulesCore
|
|
2
2
|
|
|
3
|
-
public class ScreenOrientationModule: Module,
|
|
3
|
+
public class ScreenOrientationModule: Module, ScreenOrientationController {
|
|
4
4
|
static let didUpdateDimensionsEvent = "expoDidUpdateDimensions"
|
|
5
5
|
|
|
6
6
|
let screenOrientationRegistry = ScreenOrientationRegistry.shared
|
|
@@ -22,7 +22,7 @@ public class ScreenOrientationModule: Module, OrientationListener, Hashable {
|
|
|
22
22
|
throw UnsupportedOrientationLockException(orientationLock)
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
screenOrientationRegistry.setMask(orientationMask,
|
|
25
|
+
screenOrientationRegistry.setMask(orientationMask, forController: self)
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
AsyncFunction("lockPlatformAsync") { (allowedOrientations: [ModuleOrientation]) in
|
|
@@ -43,7 +43,7 @@ public class ScreenOrientationModule: Module, OrientationListener, Hashable {
|
|
|
43
43
|
throw UnsupportedOrientationLockException(nil)
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
screenOrientationRegistry.setMask(allowedOrientationsMask,
|
|
46
|
+
screenOrientationRegistry.setMask(allowedOrientationsMask, forController: self)
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
AsyncFunction("getOrientationLockAsync") {
|
|
@@ -75,23 +75,18 @@ public class ScreenOrientationModule: Module, OrientationListener, Hashable {
|
|
|
75
75
|
return ModuleOrientation.from(orientation: screenOrientationRegistry.currentScreenOrientation).rawValue
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
-
|
|
79
|
-
screenOrientationRegistry.
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
OnStopObserving {
|
|
83
|
-
screenOrientationRegistry.unregisterModuleFromReceivingNotification(self)
|
|
78
|
+
OnCreate {
|
|
79
|
+
screenOrientationRegistry.registerController(self)
|
|
84
80
|
}
|
|
85
81
|
|
|
86
82
|
OnDestroy {
|
|
87
|
-
screenOrientationRegistry.
|
|
88
|
-
screenOrientationRegistry.moduleWillDeallocate(self)
|
|
83
|
+
screenOrientationRegistry.unregisterController(self)
|
|
89
84
|
}
|
|
90
85
|
}
|
|
91
86
|
|
|
92
|
-
// MARK: -
|
|
87
|
+
// MARK: - ScreenOrientationController
|
|
93
88
|
|
|
94
|
-
func screenOrientationDidChange(_ orientation: UIInterfaceOrientation) {
|
|
89
|
+
public func screenOrientationDidChange(_ orientation: UIInterfaceOrientation) {
|
|
95
90
|
guard let currentTraitCollection = screenOrientationRegistry.currentTraitCollection else {
|
|
96
91
|
return
|
|
97
92
|
}
|
|
@@ -105,14 +100,4 @@ public class ScreenOrientationModule: Module, OrientationListener, Hashable {
|
|
|
105
100
|
] as [String: Any]
|
|
106
101
|
])
|
|
107
102
|
}
|
|
108
|
-
|
|
109
|
-
// MARK: - Hashable
|
|
110
|
-
|
|
111
|
-
public func hash(into hasher: inout Hasher) {
|
|
112
|
-
hasher.combine(ObjectIdentifier(self))
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
public static func == (lhs: ScreenOrientationModule, rhs: ScreenOrientationModule) -> Bool {
|
|
116
|
-
return ObjectIdentifier(lhs) == ObjectIdentifier(rhs)
|
|
117
|
-
}
|
|
118
103
|
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import ExpoModulesCore
|
|
4
4
|
|
|
5
|
+
@objc(EXScreenOrientationReactDelegateHandler)
|
|
5
6
|
public class ScreenOrientationReactDelegateHandler: ExpoReactDelegateHandler {
|
|
6
7
|
public override func createRootViewController(reactDelegate: ExpoReactDelegate) -> UIViewController? {
|
|
7
8
|
return ScreenOrientationViewController(defaultScreenOrientationFromPlist: ())
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import Foundation
|
|
2
2
|
import ExpoModulesCore
|
|
3
3
|
|
|
4
|
-
protocol
|
|
4
|
+
public protocol ScreenOrientationController: AnyObject {
|
|
5
5
|
func screenOrientationDidChange(_ orientation: UIInterfaceOrientation)
|
|
6
6
|
}
|
|
7
7
|
|
|
@@ -14,10 +14,10 @@ public class ScreenOrientationRegistry: NSObject, UIApplicationDelegate {
|
|
|
14
14
|
@objc
|
|
15
15
|
public static let shared = ScreenOrientationRegistry()
|
|
16
16
|
|
|
17
|
-
var currentScreenOrientation: UIInterfaceOrientation
|
|
18
|
-
var
|
|
19
|
-
var
|
|
20
|
-
weak var currentTraitCollection: UITraitCollection?
|
|
17
|
+
public var currentScreenOrientation: UIInterfaceOrientation
|
|
18
|
+
var orientationControllers: [ScreenOrientationController] = []
|
|
19
|
+
var controllerInterfaceMasks: [ObjectIdentifier: UIInterfaceOrientationMask] = [:]
|
|
20
|
+
public weak var currentTraitCollection: UITraitCollection?
|
|
21
21
|
var lastOrientationMask: UIInterfaceOrientationMask
|
|
22
22
|
var rootViewController: UIViewController? {
|
|
23
23
|
let keyWindow = UIApplication
|
|
@@ -29,7 +29,7 @@ public class ScreenOrientationRegistry: NSObject, UIApplicationDelegate {
|
|
|
29
29
|
return keyWindow?.rootViewController
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
var currentOrientationMask: UIInterfaceOrientationMask {
|
|
32
|
+
public var currentOrientationMask: UIInterfaceOrientationMask {
|
|
33
33
|
var currentOrientationMask: UIInterfaceOrientationMask = []
|
|
34
34
|
|
|
35
35
|
EXUtilities.performSynchronously {
|
|
@@ -61,7 +61,7 @@ public class ScreenOrientationRegistry: NSObject, UIApplicationDelegate {
|
|
|
61
61
|
/**
|
|
62
62
|
Called by ScreenOrientationAppDelegate in order to set initial interface orientation.
|
|
63
63
|
*/
|
|
64
|
-
func updateCurrentScreenOrientation() {
|
|
64
|
+
public func updateCurrentScreenOrientation() {
|
|
65
65
|
let windows = UIApplication.shared.windows
|
|
66
66
|
if !windows.isEmpty {
|
|
67
67
|
self.currentScreenOrientation = windows[0].windowScene?.interfaceOrientation ?? .unknown
|
|
@@ -112,8 +112,10 @@ public class ScreenOrientationRegistry: NSObject, UIApplicationDelegate {
|
|
|
112
112
|
}
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
-
func setMask(_ mask: UIInterfaceOrientationMask,
|
|
116
|
-
|
|
115
|
+
public func setMask(_ mask: UIInterfaceOrientationMask, forController controller: any ScreenOrientationController) {
|
|
116
|
+
let controllerIdentifier = ObjectIdentifier(controller)
|
|
117
|
+
|
|
118
|
+
controllerInterfaceMasks[controllerIdentifier] = mask
|
|
117
119
|
enforceDesiredDeviceOrientation(withOrientationMask: mask)
|
|
118
120
|
}
|
|
119
121
|
|
|
@@ -124,14 +126,14 @@ public class ScreenOrientationRegistry: NSObject, UIApplicationDelegate {
|
|
|
124
126
|
*/
|
|
125
127
|
@objc
|
|
126
128
|
public func requiredOrientationMask() -> UIInterfaceOrientationMask {
|
|
127
|
-
if
|
|
129
|
+
if controllerInterfaceMasks.isEmpty {
|
|
128
130
|
return []
|
|
129
131
|
}
|
|
130
132
|
|
|
131
133
|
// We want to apply an orientation mask which is an intersection of locks applied by the modules.
|
|
132
134
|
var mask = doesDeviceHaveNotch ? UIInterfaceOrientationMask.allButUpsideDown : UIInterfaceOrientationMask.all
|
|
133
135
|
|
|
134
|
-
for moduleMask in
|
|
136
|
+
for moduleMask in controllerInterfaceMasks {
|
|
135
137
|
mask = mask.intersection(moduleMask.value)
|
|
136
138
|
}
|
|
137
139
|
|
|
@@ -231,28 +233,24 @@ public class ScreenOrientationRegistry: NSObject, UIApplicationDelegate {
|
|
|
231
233
|
}
|
|
232
234
|
|
|
233
235
|
/**
|
|
234
|
-
Called at the end of the screen orientation change. Notifies
|
|
236
|
+
Called at the end of the screen orientation change. Notifies the controllers about the orientation change.
|
|
235
237
|
*/
|
|
236
238
|
func screenOrientationDidChange(_ newScreenOrientation: UIInterfaceOrientation) {
|
|
237
239
|
currentScreenOrientation = newScreenOrientation
|
|
238
|
-
|
|
239
|
-
|
|
240
|
+
|
|
241
|
+
for controller in orientationControllers {
|
|
242
|
+
controller.screenOrientationDidChange(newScreenOrientation)
|
|
240
243
|
}
|
|
241
244
|
}
|
|
242
245
|
|
|
243
|
-
func
|
|
244
|
-
|
|
246
|
+
public func registerController(_ controller: ScreenOrientationController) {
|
|
247
|
+
orientationControllers.append(controller)
|
|
245
248
|
}
|
|
246
249
|
|
|
247
|
-
func
|
|
248
|
-
|
|
249
|
-
}
|
|
250
|
+
public func unregisterController(_ controller: ScreenOrientationController) {
|
|
251
|
+
let controllerIdentifier = ObjectIdentifier(controller)
|
|
250
252
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
if orientationListeners[i] === module || orientationListeners[i] == nil {
|
|
254
|
-
orientationListeners.remove(at: i)
|
|
255
|
-
}
|
|
256
|
-
}
|
|
253
|
+
controllerInterfaceMasks.removeValue(forKey: controllerIdentifier)
|
|
254
|
+
orientationControllers.removeAll(where: { $0 === controller })
|
|
257
255
|
}
|
|
258
256
|
}
|
|
@@ -73,6 +73,21 @@ internal func plistStringToInterfaceOrientationMask(_ maskName: String) -> UIInt
|
|
|
73
73
|
}
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
+
internal func orientationStringToInterfaceOrientationMask(_ orientationString: String) -> UIInterfaceOrientationMask? {
|
|
77
|
+
switch orientationString {
|
|
78
|
+
case "UIInterfaceOrientationPortrait":
|
|
79
|
+
return .portrait
|
|
80
|
+
case "UIInterfaceOrientationPortraitUpsideDown":
|
|
81
|
+
return .portraitUpsideDown
|
|
82
|
+
case "UIInterfaceOrientationLandscapeRight":
|
|
83
|
+
return .landscapeRight
|
|
84
|
+
case "UIInterfaceOrientationLandscapeLeft":
|
|
85
|
+
return .landscapeLeft
|
|
86
|
+
default:
|
|
87
|
+
return nil
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
76
91
|
extension UIInterfaceOrientation {
|
|
77
92
|
internal func toInterfaceOrientationMask() -> UIInterfaceOrientationMask {
|
|
78
93
|
return UIInterfaceOrientationMask(rawValue: 1 << self.rawValue)
|
|
@@ -1,34 +1,44 @@
|
|
|
1
1
|
import ExpoModulesCore
|
|
2
2
|
|
|
3
|
-
let
|
|
3
|
+
let defaultScreenOrientationMaskKey = "EXDefaultScreenOrientationMask"
|
|
4
|
+
let supportedOrientationsKey = "UISupportedInterfaceOrientations"
|
|
5
|
+
let ipadSupportedOrientationsKey = "UISupportedInterfaceOrientations~ipad"
|
|
4
6
|
|
|
5
7
|
class ScreenOrientationViewController: UIViewController {
|
|
6
8
|
let screenOrientationRegistry = ScreenOrientationRegistry.shared
|
|
7
9
|
private var defaultOrientationMask: UIInterfaceOrientationMask
|
|
8
10
|
|
|
9
|
-
init(defaultOrientationMask: UIInterfaceOrientationMask = .
|
|
11
|
+
init(defaultOrientationMask: UIInterfaceOrientationMask = doesDeviceHaveNotch ? .allButUpsideDown : .all) {
|
|
10
12
|
self.defaultOrientationMask = defaultOrientationMask
|
|
11
13
|
super.init(nibName: nil, bundle: nil)
|
|
12
14
|
}
|
|
13
15
|
|
|
14
16
|
convenience init(defaultScreenOrientationFromPlist: Void) {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
+
let supportedInterfaceOrientations = ScreenOrientationViewController.getSupportedInterfaceOrientations()
|
|
18
|
+
|
|
19
|
+
guard let orientationString = Bundle.main.object(forInfoDictionaryKey: defaultScreenOrientationMaskKey) as? String else {
|
|
20
|
+
// If user hasn't defined a default interface orientation using the config plugin use the allowed values from Info.plist as the
|
|
21
|
+
// default orientation. Values in Info.plist are set with the "orientation" key in app.json
|
|
22
|
+
self.init(defaultOrientationMask: supportedInterfaceOrientations)
|
|
17
23
|
return
|
|
18
24
|
}
|
|
19
25
|
|
|
20
26
|
guard let mask = plistStringToInterfaceOrientationMask(orientationString) else {
|
|
21
|
-
log.warn("Orientation lock string '\(orientationString)' provided in Info.plist does not correspond to a valid orientation mask. Application will default to
|
|
22
|
-
self.init(defaultOrientationMask:
|
|
27
|
+
log.warn("Orientation lock string '\(orientationString)' provided in Info.plist does not correspond to a valid orientation mask. Application will default to orientation mask set in \(supportedOrientationsKey).")
|
|
28
|
+
self.init(defaultOrientationMask: supportedInterfaceOrientations)
|
|
23
29
|
return
|
|
24
30
|
}
|
|
25
31
|
|
|
26
32
|
guard mask.isSupportedByDevice() else {
|
|
27
|
-
log.warn("Orientation lock string '\(orientationString)' provided in Info.plist is not supported by the device. Application will default to
|
|
28
|
-
self.init(defaultOrientationMask:
|
|
33
|
+
log.warn("Orientation lock string '\(orientationString)' provided in Info.plist is not supported by the device. Application will default to orientation lock set in \(supportedOrientationsKey).")
|
|
34
|
+
self.init(defaultOrientationMask: supportedInterfaceOrientations)
|
|
29
35
|
return
|
|
30
36
|
}
|
|
31
37
|
|
|
38
|
+
if mask != mask.intersection(supportedInterfaceOrientations) {
|
|
39
|
+
log.warn("Info.plist: Orientations allowed in `\(supportedOrientationsKey)` are in conflict with the values allowed in `\(defaultScreenOrientationMaskKey)`. Values from `\(defaultScreenOrientationMaskKey)` will be used. When setting the initial orientation using the config plugin delete the `\"orientation\"` key from `app.json`")
|
|
40
|
+
}
|
|
41
|
+
|
|
32
42
|
self.init(defaultOrientationMask: mask)
|
|
33
43
|
}
|
|
34
44
|
|
|
@@ -61,4 +71,27 @@ class ScreenOrientationViewController: UIViewController {
|
|
|
61
71
|
}
|
|
62
72
|
return screenWindowTraitsClass.shouldAskScreensForScreenOrientation?(in: self) ?? false
|
|
63
73
|
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Parses the lists under the key 'UISupportedInterfaceOrientations' in Info.plist into a UIInterfaceOrientation mask. Also checks for ipad specific settings.
|
|
77
|
+
* If no orientation is found all possible orientations will be returned.
|
|
78
|
+
*/
|
|
79
|
+
private static func getSupportedInterfaceOrientations() -> UIInterfaceOrientationMask {
|
|
80
|
+
let allPossibleOrientations: UIInterfaceOrientationMask = doesDeviceHaveNotch ? .allButUpsideDown : .all
|
|
81
|
+
let ipadSupportedOrientationStrings = Bundle.main.object(forInfoDictionaryKey: ipadSupportedOrientationsKey) as? [String] ?? []
|
|
82
|
+
let commonSupportedOrientationStrings = Bundle.main.object(forInfoDictionaryKey: supportedOrientationsKey) as? [String] ?? []
|
|
83
|
+
let supportedOrientationStrings = (isPad() && !ipadSupportedOrientationStrings.isEmpty) ?
|
|
84
|
+
ipadSupportedOrientationStrings : commonSupportedOrientationStrings
|
|
85
|
+
var orientationMask: UIInterfaceOrientationMask = []
|
|
86
|
+
|
|
87
|
+
for orientationString in supportedOrientationStrings {
|
|
88
|
+
guard let orientation = orientationStringToInterfaceOrientationMask(orientationString) else {
|
|
89
|
+
log.warn("Info.plist: \(orientationString) is not a valid value for the \(supportedOrientationsKey) key")
|
|
90
|
+
continue
|
|
91
|
+
}
|
|
92
|
+
orientationMask.insert(orientation)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return orientationMask.isEmpty ? allPossibleOrientations : orientationMask
|
|
96
|
+
}
|
|
64
97
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-screen-orientation",
|
|
3
|
-
"version": "6.0.
|
|
3
|
+
"version": "6.0.3",
|
|
4
4
|
"description": "Expo universal module for managing device's screen orientation",
|
|
5
5
|
"main": "build/ScreenOrientation.js",
|
|
6
6
|
"types": "build/ScreenOrientation.d.ts",
|
|
@@ -41,5 +41,5 @@
|
|
|
41
41
|
"peerDependencies": {
|
|
42
42
|
"expo": "*"
|
|
43
43
|
},
|
|
44
|
-
"gitHead": "
|
|
44
|
+
"gitHead": "8fdc53c90c52242a80ea511ee3073d9ab950bc68"
|
|
45
45
|
}
|