I would like to keep my layout the same, and only rotate views in-place when the screen orientation changes.
Below is a simple example of what I am trying to acieve. It shows to TestViews horizontally when in portrait mode, and vertically when in landscape mode.
I've made sure that the views themselve does not get re-created in the hope that it would only animate the difference in layout between portrait and landscape, but it makes the views very small, and then animate them in from the corner of the screen.
What I am trying to acieve, is for each view to effectively rotate by 90 degrees when the orientation changes. Is it possible in swiftUI?
[In my example below, I've hacked my AppDelegate to be my model to get rotation notifications from a publisher in it. This needs to be added for the example to work.]
struct TestView: View {
var text: String
var body: some View {
ZStack {
RoundedRectangle(cornerRadius: 25.0, style: .continuous)
.foregroundColor(Color(red: 0.2, green: 0.2, blue: 0.2))
Text(verbatim: text)
.font(.system(size: 95))
.foregroundColor(.white)
}.aspectRatio(1.0, contentMode: .fit)
}
}
struct ContentView: View {
@EnvironmentObject var model : AppDelegate
private let testViews: [TestView] = (0...1).map { TestView(text: "\($0)") }
var body: some View {
ZStack {
if !model.isPotrait {
HStack {
VStack {
testViews[0]
testViews[1]
}
}
} else {
VStack {
HStack {
testViews[0]
testViews[1]
}
}
}
}.padding()
}
}
Hi OOPer,
Below is my quickly hacked code to handle rotations. You could use any model that publishes isPortrait to use it as the environmental object.
class AppDelegate: UIResponder, ObservableObject, UIApplicationDelegate {
@Published var isPotrait = true
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
NotificationCenter.default.addObserver(self, selector: #selector(rotated), name: UIDevice.orientationDidChangeNotification, object: nil)
return true
}
@objc func rotated() {
self.isPotrait = UIDevice.current.orientation.isPortrait
print("isPortrait = \(isPotrait)")
}
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
}
}
You also need to add the following (or something similar) to the SceneDelegate where the ContentView is instantiated:
// Create the SwiftUI view that provides the window contents.
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let contentView = ContentView().environmentObject(appDelegate)