KodePlateform
05/28/2023, 4:39 AMUIDeviceOrientationDidChangeNotification
and have a method orientationDidChange
to handle the changes. However, it seems that orientationDidChange
is never called, and I'm not sure why.
I've checked that I've properly registered the observer and selector, but still no luck. Any insights or suggestions on why this might be happening would be greatly appreciated!
Thanks in advance for your help!
actual class ScreenOrientationObserver {
private val currentOrientation = mutableStateOf(ScreenOrientation.Portrait)
init {
class OrientationListener : NSObject() {
@Suppress("UNUSED_PARAMETER")
@ObjCAction
fun orientationDidChange(arg: NSNotification) {
val newOrientation = when (UIDevice.currentDevice.orientation) {
UIDeviceOrientation.UIDeviceOrientationPortrait,
UIDeviceOrientation.UIDeviceOrientationPortraitUpsideDown -> ScreenOrientation.Portrait
UIDeviceOrientation.UIDeviceOrientationLandscapeLeft,
UIDeviceOrientation.UIDeviceOrientationLandscapeRight -> ScreenOrientation.Landscape
else -> currentOrientation.value
}
currentOrientation.value = newOrientation
}
}
val listener = OrientationListener()
val notificationName = platform.UIKit.UIDeviceOrientationDidChangeNotification
NSNotificationCenter.defaultCenter.addObserver(
observer = listener,
selector = NSSelectorFromString(
OrientationListener::orientationDidChange.name + ":"
),
name = notificationName,
``object` = null`
)
}
actual val orientation: State<ScreenOrientation> = currentOrientation
}
actual fun createScreenOrientationObserver(): ScreenOrientationObserver {
`return ScreenOrientati`onObserver()
}orangy
KodePlateform
05/28/2023, 9:08 AMactual class ScreenOrientationObserver {
private val currentOrientation = mutableStateOf(ScreenOrientation.Portrait)
private val listener: OrientationListener = OrientationListener(currentOrientation)
init {
val notificationName = platform.UIKit.UIDeviceOrientationDidChangeNotification
NSNotificationCenter.defaultCenter.addObserver(
observer = listener,
selector = NSSelectorFromString(
OrientationListener::orientationDidChange.name + ":"
),
name = notificationName,
`object` = null
)
}
actual val orientation: State<ScreenOrientation> = currentOrientation
}
actual fun createScreenOrientationObserver(): ScreenOrientationObserver {
return ScreenOrientationObserver()
}
class OrientationListener(private val currentOrientation: MutableState<ScreenOrientation>) : NSObject() {
@Suppress("UNUSED_PARAMETER")
@ObjCAction
fun orientationDidChange(arg: NSNotification) {
val newOrientation = when (UIDevice.currentDevice.orientation) {
UIDeviceOrientation.UIDeviceOrientationPortrait,
UIDeviceOrientation.UIDeviceOrientationPortraitUpsideDown -> ScreenOrientation.Portrait
UIDeviceOrientation.UIDeviceOrientationLandscapeLeft,
UIDeviceOrientation.UIDeviceOrientationLandscapeRight -> ScreenOrientation.Landscape
else -> currentOrientation.value
}
currentOrientation.value = newOrientation
}
}
orangy
You must call this method before attempting to get orientation data from the device. This method enables the device’s accelerometer hardware and begins the delivery of acceleration events to the device. The device subsequently uses these events to post orientationDidChangeNotification notifications when the device orientation changes and to update the orientation property.
KodePlateform
05/28/2023, 10:17 AMactual class ScreenOrientationObserver {
private val currentOrientation = mutableStateOf(ScreenOrientation.Portrait)
private val listener: OrientationListener
init {
UIDevice.currentDevice.beginGeneratingDeviceOrientationNotifications()
listener = OrientationListener(currentOrientation)
val notificationName = platform.UIKit.UIDeviceOrientationDidChangeNotification
NSNotificationCenter.defaultCenter.addObserver(
observer = listener,
selector = NSSelectorFromString(
OrientationListener::orientationDidChange.name + ":"
),
name = notificationName,
`object` = null
)
}
actual val orientation: State<ScreenOrientation> = currentOrientation
// This method should be called when the observer is no longer needed
fun stopObserving() {
UIDevice.currentDevice.endGeneratingDeviceOrientationNotifications()
NSNotificationCenter.defaultCenter.removeObserver(listener)
}
}
actual fun createScreenOrientationObserver(): ScreenOrientationObserver {
return ScreenOrientationObserver()
}
class OrientationListener(private val currentOrientation: MutableState<ScreenOrientation>) : NSObject() {
@Suppress("UNUSED_PARAMETER")
@ObjCAction
fun orientationDidChange(arg: NSNotification) {
println("orientationDidChange called")
val newOrientation = when (UIDevice.currentDevice.orientation) {
UIDeviceOrientation.UIDeviceOrientationPortrait,
UIDeviceOrientation.UIDeviceOrientationPortraitUpsideDown -> ScreenOrientation.Portrait
UIDeviceOrientation.UIDeviceOrientationLandscapeLeft,
UIDeviceOrientation.UIDeviceOrientationLandscapeRight -> ScreenOrientation.Landscape
else -> currentOrientation.value
}
currentOrientation.value = newOrientation
}
}
i dont understand why on jetbrains exemple (https://github.com/JetBrains/compose-multiplatform/blob/0319db1d06dd65f09a12e1a91b[…]d/src/iosMain/kotlin/example/imageviewer/view/CameraView.ios.kt)it works and not on my codeorangy
ScreenOrientationObserver
itself is retained on a hard ref
• make sure you don’t have rotation lock enabled on a device :)KodePlateform
05/28/2023, 11:00 AMval screenOrientationObserver = remember { createScreenOrientationObserver() }
val orientation = remember { screenOrientationObserver.orientation }
Text(text = "Orientation : " + orientation.value.name)
orangy
Info.plist
https://github.com/JetBrains/compose-multiplatform/blob/0319db1d06dd65f09a12e1a91b5de758fa2d2883/examples/imageviewer/iosApp/iosApp/Info.plist#L39
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
KodePlateform
05/28/2023, 11:27 AMorangy
KodePlateform
05/28/2023, 11:29 AMDima Avdeev
05/28/2023, 4:36 PMKodePlateform
05/29/2023, 9:08 AMorangy
KodePlateform
05/29/2023, 10:37 AMimport androidx.compose.runtime.MutableState
import androidx.compose.runtime.State
import androidx.compose.runtime.mutableStateOf
import kotlinx.cinterop.ObjCAction
import platform.Foundation.NSNotification
import platform.Foundation.NSNotificationCenter
import platform.Foundation.NSSelectorFromString
import platform.UIKit.UIDevice
import platform.UIKit.UIDeviceOrientation
import platform.darwin.NSObject
actual class ScreenOrientationObserver {
private val currentOrientation = mutableStateOf(ScreenOrientation.Portrait)
private val listener: OrientationListener
init {
UIDevice.currentDevice.beginGeneratingDeviceOrientationNotifications()
listener = OrientationListener(currentOrientation)
val notificationName = platform.UIKit.UIDeviceOrientationDidChangeNotification
NSNotificationCenter.defaultCenter.addObserver(
observer = listener,
selector = NSSelectorFromString(
OrientationListener::orientationDidChange.name + ":"
),
name = notificationName,
`object` = null
)
}
actual val orientation: State<ScreenOrientation> = currentOrientation
// This method should be called when the observer is no longer needed
fun stopObserving() {
UIDevice.currentDevice.endGeneratingDeviceOrientationNotifications()
NSNotificationCenter.defaultCenter.removeObserver(listener)
}
}
actual fun createScreenOrientationObserver(): ScreenOrientationObserver {
return ScreenOrientationObserver()
}
class OrientationListener(private val currentOrientation: MutableState<ScreenOrientation>) : NSObject() {
@Suppress("UNUSED_PARAMETER")
@ObjCAction
fun orientationDidChange(arg: NSNotification) {
println("orientationDidChange called")
val newOrientation = when (UIDevice.currentDevice.orientation) {
UIDeviceOrientation.UIDeviceOrientationPortrait,
UIDeviceOrientation.UIDeviceOrientationPortraitUpsideDown -> ScreenOrientation.Portrait
UIDeviceOrientation.UIDeviceOrientationLandscapeLeft,
UIDeviceOrientation.UIDeviceOrientationLandscapeRight -> ScreenOrientation.Landscape
else -> currentOrientation.value
}
currentOrientation.value = newOrientation
}
}
with in commonMain :
expect fun createScreenOrientationObserver(): ScreenOrientationObserver
enum class ScreenOrientation {
Landscape,
Portrait,
}
expect class ScreenOrientationObserver() {
val orientation: State<ScreenOrientation>
}
and for usage :
val screenOrientationObserver = remember { createScreenOrientationObserver() }
val orientation = remember { screenOrientationObserver.orientation }
if (orientation.value == ScreenOrientation.Landscape) {}
KodePlateform
05/29/2023, 10:40 AMactual class ScreenOrientationObserver {
private val currentOrientation = mutableStateOf(ScreenOrientation.Portrait)
init {
val orientation = MainApp.appContext.resources.configuration.orientation // appContext is an android Context
if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
currentOrientation.value = ScreenOrientation.Landscape
} else if (orientation == Configuration.ORIENTATION_PORTRAIT) {
currentOrientation.value = ScreenOrientation.Portrait
}
}
actual val orientation: State<ScreenOrientation> = currentOrientation
}
actual fun createScreenOrientationObserver(): ScreenOrientationObserver {
return ScreenOrientationObserver()
}