我正在使用Swift,当我旋转到横向模式时,我想要能够加载一个UIViewController,有人可以指点我一下吗?
我在网上找不到任何信息,对文档感到有点困惑。
我正在使用Swift,当我旋转到横向模式时,我想要能够加载一个UIViewController,有人可以指点我一下吗?
我在网上找不到任何信息,对文档感到有点困惑。
以下是我如何使它工作的:
在AppDelegate.swift
中的didFinishLaunchingWithOptions
函数内,我添加了以下代码:
NotificationCenter.default.addObserver(self, selector: #selector(AppDelegate.rotated), name: UIDevice.orientationDidChangeNotification, object: nil)
然后在AppDelegate类内部,我加入了以下函数:
func rotated() {
if UIDeviceOrientationIsLandscape(UIDevice.current.orientation) {
print("Landscape")
}
if UIDeviceOrientationIsPortrait(UIDevice.current.orientation) {
print("Portrait")
}
}
selector
的字符串格式不应该是 "rotated:"
吗? - Chameleonrotated()
并不接受参数)。 - DavidUIDeviceOrientation
与UIInterfaceOrientation
是不同的东西。这是因为UIDeviceOrientation
还可以检测面朝下和面朝上的方向,这意味着如果您的设备静置在接近平坦但略微不平整的表面上(例如6/6s相机凸出部分上晃动),那么您的代码可能会随机在纵向和横向之间跳转。 - liamnicholsoverride func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
if UIDevice.current.orientation.isLandscape {
print("Landscape")
}
if UIDevice.current.orientation.isFlat {
print("Flat")
} else {
print("Portrait")
}
}
我需要在使用 AVFoundation
摄像头时检测旋转,发现 didRotate
(现已弃用) 和 willTransition
方法无法满足我的需求。使用 David 发布的通知确实有效,但不适用于 Swift 3.x 及以上版本。
以下使用了闭包,这似乎是 Apple 推荐的方式。
var didRotate: (Notification) -> Void = { notification in
switch UIDevice.current.orientation {
case .landscapeLeft, .landscapeRight:
print("landscape")
case .portrait, .portraitUpsideDown:
print("Portrait")
default:
print("other (such as face up & down)")
}
}
设置通知:
NotificationCenter.default.addObserver(forName: UIDevice.orientationDidChangeNotification,
object: nil,
queue: .main,
using: didRotate)
撤销通知:
NotificationCenter.default.removeObserver(self,
name: UIDevice.orientationDidChangeNotification,
object: nil)
关于弃用声明: 我最初的评论可能有误导性,所以我想进行更新。如注所述,使用@objc
推断已被弃用,这反过来需要使用#selector
。通过使用闭包,可以避免这种情况,并且现在您有一个解决方案,应该避免调用无效选择器而导致崩溃。
使用UIDevice
的-orientation
属性是不正确的(即使在大多数情况下它可能会工作),并且可能会导致一些错误,例如UIDeviceOrientation
还考虑设备是否面朝上或面朝下,而对于这些值,UIInterfaceOrientation
枚举中没有直接的对应项。
此外,如果您锁定了应用程序在某个特定方向上,则UIDevice将给出不考虑该方向的设备方向。
另一方面,iOS8已经弃用了UIViewController
类上的interfaceOrientation
属性。
有两个选项可用于检测界面方向:
仍然缺少的是了解界面方向更改方向的方法,这在动画过程中非常重要。
在WWDC 2014“ iOS8中的视图控制器进展”会议上,演讲者还提供了解决该问题的方法,使用替换-will/DidRotateToInterfaceOrientation
的方法。
这里提出的解决方案部分实现,更多信息here:
func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
let orientation = orientationFromTransform(coordinator.targetTransform())
let oldOrientation = UIApplication.sharedApplication().statusBarOrientation
myWillRotateToInterfaceOrientation(orientation,duration: duration)
coordinator.animateAlongsideTransition({ (ctx) in
self.myWillAnimateRotationToInterfaceOrientation(orientation,
duration:duration)
}) { (ctx) in
self.myDidAnimateFromInterfaceOrientation(oldOrientation)
}
}
iOS 8以后,这是正确的方法。
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
coordinator.animate(alongsideTransition: { context in
// This is called during the animation
}, completion: { context in
// This is called after the rotation is finished. Equal to deprecated `didRotate`
})
}
NotificationCenter.default.addObserver(self, selector: #selector(AppDelegate.rotated), name: UIDevice.orientationDidChangeNotification, object: nil)
更好的答案。UIDeviceOrientation 的问题在于它检测到我们不需要的面朝下和面朝上的方向。 - Kirill我知道这个问题是关于Swift
的,但由于它是谷歌搜索中排名靠前的链接之一,如果你想在Objective-C
中寻找相同的代码:
// add the observer
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(rotated:) name:UIDeviceOrientationDidChangeNotification object:nil];
// remove the observer
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil];
// method signature
- (void)rotated:(NSNotification *)notification {
// do stuff here
}
我喜欢检查方向通知,因为您可以在任何类中添加此功能,无需是视图或视图控制器。甚至可以在您的应用程序委托中使用。
SWIFT 5:
//ask the system to start notifying when interface change
UIDevice.current.beginGeneratingDeviceOrientationNotifications()
//add the observer
NotificationCenter.default.addObserver(
self,
selector: #selector(orientationChanged(notification:)),
name: UIDevice.orientationDidChangeNotification,
object: nil)
比起缓存通知
@objc func orientationChanged(notification : NSNotification) {
//your code there
}
非常简单,在iOS8、9/Swift2/Xcode7中有效,只需将以下代码放入您的viewcontroller.swift中。每次屏幕方向更改时,它都会打印屏幕尺寸,您可以放置自己的代码代替:
override func didRotateFromInterfaceOrientation(fromInterfaceOrientation: UIInterfaceOrientation) {
getScreenSize()
}
var screenWidth:CGFloat=0
var screenHeight:CGFloat=0
func getScreenSize(){
screenWidth=UIScreen.mainScreen().bounds.width
screenHeight=UIScreen.mainScreen().bounds.height
print("SCREEN RESOLUTION: "+screenWidth.description+" x "+screenHeight.description)
}
didRotateFromInterfaceOrientation()
的可靠性不高。它会错过一些旋转。iewWillTransitionToSize:withTransitionCoordinator:
运行良好。 - Andrej在Objective C中
-(void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator)
重写此方法以检测方向更改。