ios程序中发现个问题:
对于已知的屏幕方向的定义:
public enum UIInterfaceOrientation : Int {
case unknown
case portrait
case portraitUpsideDown
case landscapeLeft
case landscapeRight
}
public enum UIDeviceOrientation : Int {
case unknown
case portrait // Device oriented vertically, home button on the bottom
case portraitUpsideDown // Device oriented vertically, home button on the top
case landscapeLeft // Device oriented horizontally, home button on the right
case landscapeRight // Device oriented horizontally, home button on the left
case faceUp // Device oriented flat, face up
case faceDown // Device oriented flat, face down
}
在设备屏幕从:竖屏,变成 横屏
点击Home 键进入后台
再点击app图标回到 前台
后,设备的方向,却从之前的横屏,变成了竖屏:
代码:
func applicationWillResignActive(_ application: UIApplication) {
print(“applicationWillResignActive UIDevice.current.orientation.rawValue=\(UIDevice.current.orientation.rawValue)”)
}
func applicationDidEnterBackground(_ application: UIApplication) {
print(“applicationDidEnterBackground UIDevice.current.orientation.rawValue=\(UIDevice.current.orientation.rawValue)”)
}
func applicationWillEnterForeground(_ application: UIApplication) {
print(“applicationWillEnterForeground UIDevice.current.orientation.rawValue=\(UIDevice.current.orientation.rawValue)”)
}
func applicationDidBecomeActive(_ application: UIApplication) {
print(“applicationDidBecomeActive UIDevice.current.orientation.rawValue=\(UIDevice.current.orientation.rawValue)”)
}
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
print(“supportedInterfaceOrientationsFor UIDevice.current.orientation.rawValue=\(UIDevice.current.orientation.rawValue)”)
}
log输出:
applicationWillResignActive UIDevice.current.orientation.rawValue=4
applicationDidEnterBackground UIDevice.current.orientation.rawValue=4
applicationWillEnterForeground UIDevice.current.orientation.rawValue=1
applicationDidBecomeActive UIDevice.current.orientation.rawValue=1
进入后台前是:rawValue=4=landscapeRight
恢复后回到前台却变成了:rawValue=1=portrait
导致:
后续的虽然调用了:
extension UIDevice {
static func rotateTo(newDirection:UIInterfaceOrientation) {
self.current.setValue(newDirection.rawValue, forKey: “orientation”)
}
static func rotateToIfNeed(newDirection:UIInterfaceOrientation) {
if !self.isOrientation(toCmpOrientation: newDirection) {
self.rotateTo(newDirection: newDirection)
}
}
static func isOrientation(toCmpOrientation:UIInterfaceOrientation) -> Bool {
//Note:
// self.current.orientation is UIDeviceOrientation
// toCmpOrientation is UIInterfaceOrientation
// but first 5 type: unknown/portrait/portraitUpsideDown/landscapeLeft/landscapeRight
// of enum value is equal
return self.current.orientation.rawValue == toCmpOrientation.rawValue
}
}
中的:
rotateTo结果却不起效果。
ios back from background UIDevice orientation change to portrait
ios back from background UIDevice orientation changed
ios return from background UIDevice orientation changed
ios8 – How to change device orientation when app returns to foreground in iOS – Stack Overflow
objective c – How to check the orientation of device programmatically in iPhone? – Stack Overflow
ios – How to detect orientation change? – Stack Overflow
uideviceorientation – How to detect iOS device orientation from background? – Stack Overflow
screen – How to change device orientation when app returns to foreground in iOS? – Stack Overflow
结果用代码:
func applicationDidEnterBackground(_ application: UIApplication) {
self.devOrientationBeforeIntoBkg = UIDevice.current.orientation@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate,UINavigationControllerDelegate,JPUSHRegisterDelegate{
let curVersion = AppVersion()
var disableRotation: Bool = false
var devOrientationBeforeIntoBkg = UIDeviceOrientation.unknown
…
}
print(“applicationDidEnterBackground UIDevice.current.orientation.rawValue=\(UIDevice.current.orientation.rawValue)”)
}
func applicationWillEnterForeground(_ application: UIApplication) {
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
print(“applicationWillEnterForeground UIDevice.current.orientation.rawValue=\(UIDevice.current.orientation.rawValue)”)
let prevOrientation:UIInterfaceOrientation = UIInterfaceOrientation(rawValue: self.devOrientationBeforeIntoBkg.rawValue)!
UIDevice.rotateToIfNeed(newDirection: prevOrientation)
print(“applicationWillEnterForeground after rotated: UIDevice.current.orientation.rawValue=\(UIDevice.current.orientation.rawValue)”)
}
强制在applicationWillEnterForeground时,从rawValue=1转换为rawValue=4
但是结果applicationDidBecomeActive时,却还是rawValue=1
applicationWillResignActive UIDevice.current.orientation.rawValue=4
applicationDidEnterBackground UIDevice.current.orientation.rawValue=4
applicationWillEnterForeground UIDevice.current.orientation.rawValue=1
applicationWillEnterForeground after rotated: UIDevice.current.orientation.rawValue=4
applicationDidBecomeActive UIDevice.current.orientation.rawValue=1
后来把同样的转换代码放到applicationDidBecomeActive:
func applicationDidBecomeActive(_ application: UIApplication) {
print(“applicationDidBecomeActive UIDevice.current.orientation.rawValue=\(UIDevice.current.orientation.rawValue)”)
let prevOrientation:UIInterfaceOrientation = UIInterfaceOrientation(rawValue: self.devOrientationBeforeIntoBkg.rawValue)!
UIDevice.rotateToIfNeed(newDirection: prevOrientation)
print(“applicationDidBecomeActive after rotateToIfNeed: UIDevice.current.orientation.rawValue=\(UIDevice.current.orientation.rawValue)”)
}
就可以了:
applicationWillResignActive UIDevice.current.orientation.rawValue=4
applicationDidEnterBackground UIDevice.current.orientation.rawValue=4
applicationWillEnterForeground UIDevice.current.orientation.rawValue=1
applicationWillEnterForeground after rotated: UIDevice.current.orientation.rawValue=4
applicationDidBecomeActive UIDevice.current.orientation.rawValue=1
supportedInterfaceOrientationsFor UIDevice.current.orientation.rawValue=4
applicationDidBecomeActive after rotateToIfNeed: UIDevice.current.orientation.rawValue=4
【总结】
所以核心的逻辑是:
在(从后台恢复到前台active的)applicationDidBecomeActive时,去执行:UIDevice的rotate:
func applicationDidBecomeActive(_ application: UIApplication) {
print(“applicationDidBecomeActive UIDevice.current.orientation.rawValue=\(UIDevice.current.orientation.rawValue)”)
if (self.devOrientationBeforeIntoBkg != UIDeviceOrientation.unknown) {
let prevOrientation:UIInterfaceOrientation = UIInterfaceOrientation(rawValue: self.devOrientationBeforeIntoBkg.rawValue)!
UIDevice.rotateToIfNeed(newDirection: prevOrientation)
}
print(“applicationDidBecomeActive after rotateToIfNeed: UIDevice.current.orientation.rawValue=\(UIDevice.current.orientation.rawValue)”)
}
才可以把,现在不正常的设备方向:
UIDevice.current.orientation.rawValue=1=portrait
转换为正常的,进入后台前的
UIDevice.current.orientation.rawValue=4=landscapeRight
-》从而使得后续的页面旋转正常工作。
最后的代码是:
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate,UINavigationControllerDelegate,JPUSHRegisterDelegate{
let curVersion = AppVersion()
var disableRotation: Bool = false
var devOrientationBeforeIntoBkg = UIDeviceOrientation.unknown
…
}
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
self.devOrientationBeforeIntoBkg = UIDevice.current.orientation
return true
}
func applicationDidEnterBackground(_ application: UIApplication) {
self.devOrientationBeforeIntoBkg = UIDevice.current.orientation
}
func applicationDidBecomeActive(_ application: UIApplication) {
if (self.devOrientationBeforeIntoBkg != UIDeviceOrientation.unknown) {
let prevOrientation:UIInterfaceOrientation = UIInterfaceOrientation(rawValue: self.devOrientationBeforeIntoBkg.rawValue)!
UIDevice.rotateToIfNeed(newDirection: prevOrientation)
}
}
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
if self.disableRotation {
return DeviceDirectionMaskReportDetail
} else {
return DeviceDirectionMaskAppDefault
}
}
期间调试时输出是:
didFinishLaunchingWithOptions UIDevice.current.orientation.rawValue=0
applicationDidBecomeActive UIDevice.current.orientation.rawValue=1
applicationDidBecomeActive after rotateToIfNeed: UIDevice.current.orientation.rawValue=1
applicationWillResignActive UIDevice.current.orientation.rawValue=4
applicationDidEnterBackground UIDevice.current.orientation.rawValue=4
applicationWillEnterForeground UIDevice.current.orientation.rawValue=1
supportedInterfaceOrientationsFor UIDevice.current.orientation.rawValue=4
supportedInterfaceOrientationsFor UIDevice.current.orientation.rawValue=4
applicationDidBecomeActive after rotateToIfNeed: UIDevice.current.orientation.rawValue=4