How to detect device rotation in SwiftUI and re-draw view components?
I have a @State variable initialized to the value of UIScreen.main.bounds.width when the first appears. But this value doesn't change when the device orientation changes. I need to redraw all components when the user changes the device orientation.
SwiftUI's rotation3DEffect() modifier lets us rotate views in 3D space to create beautiful effects in almost no code. It accepts two parameters: what angle to rotate (in degrees or radians), plus a tuple containing the X, Y, and Z axis around which to perform the rotation.
SwiftUI doesn't have a built-in way to detect the user rotating their device between portrait and landscape orientation, but we can make one using a custom modifier by responding to the UIDevice. orientationDidChangeNotification notification.
In order to determine the Orientation of the screen, we can use the OrientationBuilder Widget. The OrientationBuilder will determine the current Orientation and rebuild when the Orientation changes.
Here‘s an idiomatic SwiftUI implementation based on a notification publisher:
struct ContentView: View { @State var orientation = UIDevice.current.orientation let orientationChanged = NotificationCenter.default.publisher(for: UIDevice.orientationDidChangeNotification) .makeConnectable() .autoconnect() var body: some View { Group { if orientation.isLandscape { Text("LANDSCAPE") } else { Text("PORTRAIT") } }.onReceive(orientationChanged) { _ in self.orientation = UIDevice.current.orientation } } }
The output of the publisher (not used above, therefor _
as the block parameter) also contains the key "UIDeviceOrientationRotateAnimatedUserInfoKey"
in its userInfo
property if you need to know if the rotation should be animated.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With