之前已经写了关于iOS中屏幕方向的函数:
import UIKit 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 { return self.current.orientation.rawValue == toCmpOrientation.rawValue } } |
但是在调试期间,用其他函数传入之前的设备方向时:
let reportDetailsVC = ReportDetailsViewController(url: url as! String, title:titleC, prevOrientation: UIDevice.current.orientation) |
结果报错:
ReportViewController.swift:111:132: Cannot convert value of type ‘UIDeviceOrientation’ to type ‘UIInterfaceOrientation’ in coercion
-》
然后才注意到自己之前写的:
return self.current.orientation.rawValue == toCmpOrientation.rawValue
其实好像不对:
self.current.orientation是UIDeviceOrientation
而toCmpOrientation是UIInterfaceOrientation
两个不是一个类型
定义分别是:
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 } |
和
// Note that UIInterfaceOrientationLandscapeLeft is equal to UIDeviceOrientationLandscapeRight (and vice versa). // This is because rotating the device to the left requires rotating the content to the right. public enum UIInterfaceOrientation : Int { case unknown case portrait case portraitUpsideDown case landscapeLeft case landscapeRight } |
很明显是:
UIDeviceOrientation和UIInterfaceOrientation的基本的定义是一样的
UIDeviceOrientation比UIInterfaceOrientation多了两个faceUp和faceDown
所以:
如果把UIInterfaceOrientation的rawValue强制转换为UIDeviceOrientation则是行得通的
反过来就不行。
-》所以刚以为:
return self.current.orientation.rawValue == toCmpOrientation.rawValue
是有问题的,实际上是可行的。至少是可以达到此处的基本目的的:判断设备方向是否一致。
而对于此处,设置设备方向用代码:
static func rotateTo(newDirection:UIInterfaceOrientation) {
self.current.setValue(newDirection.rawValue, forKey: “orientation”)
}
其中用的是UIInterfaceOrientation,而不是UIDeviceOrientation,的诡异之处
ios UIDevice set Orientation
ios – How do I programmatically set device orientation in iOS7? – Stack Overflow
中提到了:
// Set device orientation // Important: // • Passing a UIDeviceOrientation here doesn’t work, but passing a UIInterfaceOrientation does // • This is a hack, and could stop working at any moment UIDevice.current.setValue(interfaceOrientation.rawValue, forKey: “orientation”) |
中的“②系统横竖屏开关关闭时
如果关闭了系统的横竖屏切换开关,即系统层级只允许竖屏时,再通过上述方式获取到的设备方向将永远是UIDeviceOrientationUnknown。可以通过Core Motion中的CMMotionManager来获取当前设备方向。”
需要后续注意是否有此问题。
【总结】
所以此处暂时可以用:
let prevInterfaceOrientation:UIInterfaceOrientation = UIInterfaceOrientation(rawValue: UIDevice.current.orientation.rawValue)! |
去实现,从UIDeviceOrientation强制转换为UIInterfaceOrientation
当前也要确保前提是:此处UIDeviceOrientation不会出现faceUp和faceDown
否则转换是会出错的。
这样的话,就可以继续用之前的:
// // CrifanDevice.swift // Crifan Li // Updated: 2017/11/09 // import UIKit 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 } } |
了,调用举例:
let DeviceDirectionAppDefault = UIInterfaceOrientation.portrait let DeviceDirectionReportDetail = UIInterfaceOrientation.landscapeLeft UIDevice.rotateToIfNeed(newDirection: DeviceDirectionReportDetail) |
完整库函数请参考:
https://github.com/crifan/crifanLib/blob/master/swift/Device/CrifanDevice.swift
转载请注明:在路上 » 【已解决】iOS中屏幕方向警告:Cannot convert value of type UIDeviceOrientation to type UIInterfaceOrientation in coercion