iPhone 方向与转屏

iOS 6中通过代码启用转屏支持

通过查看文档,用于控制系统屏幕方向的枚举如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
// iOS 6 及之后版本用于控制屏幕方向的枚举
struct UIInterfaceOrientationMask : RawOptionSetType {
init(_ rawValue: UInt)
init(rawValue: UInt)
static var Portrait: UIInterfaceOrientationMask { get }
static var LandscapeLeft: UIInterfaceOrientationMask { get }
static var LandscapeRight: UIInterfaceOrientationMask { get }
static var PortraitUpsideDown: UIInterfaceOrientationMask { get }
static var Landscape: UIInterfaceOrientationMask { get }
static var All: UIInterfaceOrientationMask { get }
static var AllButUpsideDown: UIInterfaceOrientationMask { get }
}

App 级别方向控制

Supported interface orientations

对应info.plist

1
2
3
4
5
6
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeRight</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
</array>

单个 View Controller 方向控制

在 iOS 6 及之后的版本,单个界面的屏幕方向控制,要使用 UIViewController 在 iOS 6.0 中新增加的两个方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 是否支持转屏
override func shouldAutorotate() -> Bool {
return true
}
// 支持的屏幕方向,此处可直接返回 UIInterfaceOrientationMask 类型
// 也可以返回多个 UIInterfaceOrientationMask 取或运算后的值
override func supportedInterfaceOrientations() -> Int {
return Int(UIInterfaceOrientationMask.Portrait.rawValue)
}
// 在支持的方向中,设定最高优先级
override func preferredInterfaceOrientationForPresentation() -> UIInterfaceOrientation {
return .LandscapeRight
}

P.S. 每个Controller中都可以单独配置View是否支持转屏,但只能调用info.plist所支持的方向,否则会Crash,丢出一个UIApplicationInvalidInterfaceOrientationException。优先级也同理。

1
2
3
Terminating app due to uncaught exception UIApplicationInvalidInterfaceOrientation',
reason: 'Supported orientations has no common orientation with the application,
and [RorateTest.OrientationNav shouldAutorotate] is returning YES'

其中 supportedInterfaceOrientations 方法在 iPad 中默认取值为 UIInterfaceOrientationMaskAll,即默认支持所有屏幕方向;而 iPhone 跟 iPod Touch 的默认取值为 UIInterfaceOrientationMaskAllButUpsideDown,即支持除竖屏向下以外的三个方向。

在设备屏幕旋转时,系统会调用 shouldAutorotate 方法检查当前界面是否支持旋转,只有 shouldAutorotate 返回 YES 的时候,supportedInterfaceOrientations 方法才会被调用,以确定是否需要旋转界面。

实战一:推入一个新的View,强制从Portrait变为Landscape

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# 第一个Portrait Navigation ControllerClass(在Storyboard中设置)
class PortraitNavController: UINavigationController {
override func shouldAutorotate() -> Bool {
return true
}
override func supportedInterfaceOrientations() -> Int {
var portrait = Int(UIInterfaceOrientationMask.Portrait.rawValue)
return portrait
}
}
# Landscape Navigation ControllerClass(推入后,默认为LandscapeRight)
class LanscapeNavController: UINavigationController {
override func shouldAutorotate() -> Bool {
return true
}
override func supportedInterfaceOrientations() -> Int {
var landspace = Int(UIInterfaceOrientationMask.Landscape.rawValue)
return landspace
}
}
# 推入新的ViewController
var mainStroyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
var controller: OrientationNav2Controller = mainStroyboard.instantiateViewControllerWithIdentifier("landscapeNavLandscape") as LanscapeNavController
self.navigationController?.presentViewController(controller, animated: true, completion: nil)
# 关闭Landscape ControllerView 变为Portrait
self.navigationController!.dismissViewControllerAnimated(true, completion: nil)

实战2:当前View旋转

像Youku一样,当前View,点击转屏

REF::