Hello,
The following function is triggered whenever the device is rotated, except in the case when I "flip" the device along it's X axis when in landscape mode.
override func willTransition(to newCollection: UITraitCollection, with coordinator: UIViewControllerTransitionCoordinator) {
print("orientation after activity = " + String(UIDevice.current.orientation.rawValue))
}
If I hold a device in landscape mode, and then rotate it away from me, so that the screen is facing away, the view rotates, but the willTransition func is not triggered. So if I am starting out in landscape left with the device facing me, and then do my "flip", it's essentially now landscape right with the screen facing away from me.
I am building a "flip mode" in my app where I want two specific views to rotate, but I don't want the entire window to rotate. I can't seem to figure out how to detect this transition so that I can properly handle it in my code.
I did some more tests, with a CollectionView
override func willTransition(to newCollection: UITraitCollection, with coordinator: UIViewControllerTransitionCoordinator) {
super.willTransition(to: newCollection, with: coordinator)
print("orientation after activity = " + String(UIDevice.current.orientation.rawValue), newCollection)
}
Then, I rotate Left (from Portrait): newCollection for Landscape Left
orientation after activity = 3 <UITraitCollection: 0x6000010d8b00; _UITraitNameUserInterfaceIdiom = Phone, _UITraitNameDisplayScale = 2.000000, _UITraitNameDisplayGamut = sRGB, _UITraitNameHorizontalSizeClass = Compact, _UITraitNameVerticalSizeClass = Compact, _UITraitNameUserInterfaceStyle = 1, _UITraitNameUserInterfaceLayoutDirection = 0, _UITraitNameForceTouchCapability = 1, _UITraitNamePreferredContentSizeCategory = UICTContentSizeCategoryL>
Then, rotaote right and right again
newCollection for Portrait
orientation after activity = 1 <UITraitCollection: 0x6000010d1280; _UITraitNameUserInterfaceIdiom = Phone, _UITraitNameDisplayScale = 2.000000, _UITraitNameDisplayGamut = sRGB, _UITraitNameHorizontalSizeClass = Compact, _UITraitNameVerticalSizeClass = Regular, _UITraitNameUserInterfaceStyle = 1, _UITraitNameUserInterfaceLayoutDirection = 0, _UITraitNameForceTouchCapability = 1, _UITraitNamePreferredContentSizeCategory = UICTContentSizeCategoryL>
newCollection for Landscape Right
orientation after activity = 4 <UITraitCollection: 0x6000010d4b00; _UITraitNameUserInterfaceIdiom = Phone, _UITraitNameDisplayScale = 2.000000, _UITraitNameDisplayGamut = sRGB, _UITraitNameHorizontalSizeClass = Compact, _UITraitNameVerticalSizeClass = Compact, _UITraitNameUserInterfaceStyle = 1, _UITraitNameUserInterfaceLayoutDirection = 0, _UITraitNameForceTouchCapability = 1, _UITraitNamePreferredContentSizeCategory = UICTContentSizeCategoryL>
We can see that UITraitCollection only differ by _UITraitNameVerticalSizeClass = Compact or Regular
But for landscape Left or Right, they are exactly the same.
Hence, when you flip, UITraitCollection does not change.
Looking at doc:
willTransition(to:with:)
Notifies the container that its trait collection changed.
So, when you flip, UITraitCollection does not change at all. Hence, willTransition is not called.
What I understand is that
- if x, y are axes of the plane of the phone screen and z the axis from front to back
- willTransition detects rotation along the z-axis but not along x or y (your flip is along y-axis)
As a conclusion: the behavior is normal even though a bit disappointing not to be able to detect the flip.
Maybe you could detect the flip directly (with motion sensors).
But there is probably a simpler way: detect that the whole view has flipped.
I added in ViewController:
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
print("orientation of view = \(size)")
}
Then, rotating Left (to Landscape) and then change orientation directly to Landscape Right, I get
orientation after activity = 3 <UITraitCollection: 0x600002002e00; _UITraitNameUserInterfaceIdiom = Phone, _UITraitNameDisplayScale = 2.000000, _UITraitNameDisplayGamut = sRGB, _UITraitNameHorizontalSizeClass = Compact, _UITraitNameVerticalSizeClass = Compact, _UITraitNameUserInterfaceStyle = 1, _UITraitNameUserInterfaceLayoutDirection = 0, _UITraitNameForceTouchCapability = 1, _UITraitNamePreferredContentSizeCategory = UICTContentSizeCategoryL>
orientation of view = (568.0, 320.0)
orientation of view = (568.0, 320.0)
Which show that viewWillTransition was triggered. Even though the size did not change !
So, behavior is a bit inconsistent across APIs.
You could file a bug or enhancement report.
I will have to manually do this swapping. It'll be a little tricky, since I am using autolayout,
As for adapting the content, you certainly have to do it in code.
I would do it by changing the constraints in code: you probably have just a bunch of them (I guess, an enclosing view for each team, then just have to change some trailing and leading constraints, may be horizontal spacing as well).