Dav*_*vid 142 orientation-changes ios swift
我正在使用Swift,我希望能够在旋转到横向时加载UIViewController,任何人都可以指向正确的方向吗?
我在网上找不到任何东西,文档也有点困惑.
Dav*_*vid 186
以下是我如何使用它:
在 我放AppDelegate.swift
的didFinishLaunchingWithOptions
功能里面:
NotificationCenter.default.addObserver(self, selector: #selector(AppDelegate.rotated), name: UIDevice.orientationDidChangeNotification, object: nil)
Run Code Online (Sandbox Code Playgroud)
然后在AppDelegate类里面我放了以下函数:
func rotated() {
if UIDeviceOrientationIsLandscape(UIDevice.current.orientation) {
print("Landscape")
}
if UIDeviceOrientationIsPortrait(UIDevice.current.orientation) {
print("Portrait")
}
}
Run Code Online (Sandbox Code Playgroud)
希望这有助于其他任何人!
谢谢!
小智 172
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
if UIDevice.current.orientation.isLandscape {
print("Landscape")
if UIDevice.current.orientation.isFlat {
print("Flat")
} else {
print("Portrait")
}
}
Run Code Online (Sandbox Code Playgroud)
Cod*_*der 58
需要在使用相机时检测旋转AVFoundation
,并发现didRotate
(现已弃用)和willTransition
方法对我的需求不可靠.使用David发布的通知确实有效,但对于Swift 3.x/4.x来说不是最新的.
Swift 4.2 通知名称已更改.
闭包值与Swift 4.0保持一致:
var didRotate: (Notification) -> Void = { notification in
switch UIDevice.current.orientation {
case .landscapeLeft, .landscapeRight:
print("landscape")
case .portrait, .portraitUpsideDown:
print("Portrait")
default:
print("other")
}
}
Run Code Online (Sandbox Code Playgroud)
要设置Swift 4.2的通知:
NotificationCenter.default.addObserver(forName: UIDevice.orientationDidChangeNotification,
object: nil,
queue: .main,
using: didRotate)
Run Code Online (Sandbox Code Playgroud)
要删除Swift 4.2的通知:
NotificationCenter.default.removeObserver(self,
name: UIDevice.orientationDidChangeNotification,
object: nil)
Run Code Online (Sandbox Code Playgroud)
关于弃用声明,我的初步评论具有误导性,所以我想更新一下.如上所述,@objc
推理的使用已被弃用,而这又需要使用#selector
.通过使用闭包,可以避免这种情况,现在您可以使用一个解决方案来避免因调用无效选择器而导致崩溃.
Swift 4.0
使用Swift 4.0,Apple鼓励我们避免使用#selector
,因此这种方法现在使用完成块.这种方法也向后兼容Swift 3.x并且将是未来推荐的方法.
如果#selector
由于@objc
推断的弃用而使用该函数,那么您将在Swift 4.x项目中收到编译器警告:
设置回调:
// If you do not use the notification var in your callback,
// you can safely replace it with _
var didRotate: (Notification) -> Void = { notification in
switch UIDevice.current.orientation {
case .landscapeLeft, .landscapeRight:
print("landscape")
case .portrait, .portraitUpsideDown:
print("Portrait")
default:
print("other")
}
}
Run Code Online (Sandbox Code Playgroud)
设置通知:
NotificationCenter.default.addObserver(forName: .UIDeviceOrientationDidChange,
object: nil,
queue: .main,
using: didRotate)
Run Code Online (Sandbox Code Playgroud)
撕下来:
NotificationCenter.default.removeObserver(self, name: .UIDeviceOrientationDidChange, object: nil)
Run Code Online (Sandbox Code Playgroud)
And*_*rea 18
使用-orientation
属性UIDevice
是不正确的(即使它可以在大多数情况下工作)并且可能导致一些错误,例如UIDeviceOrientation
,如果设备朝上或朝下,也考虑设备的方向,UIInterfaceOrientation
那些枚举中没有直接对值.
此外,如果您将应用程序锁定在某个特定方向,UIDevice将为您提供设备方向,而不考虑这一点.
另一方面,iOS8已经interfaceOrientation
在UIViewController
课堂上弃用了该属性.
有两个选项可用于检测界面方向:
仍然缺少的是一种理解界面方向变化方向的方法,这在动画期间非常重要.
在WWDC 2014"在iOS8中查看控制器进展"的会话中,扬声器也使用替换的方法提供了该问题的解决方案 -will/DidRotateToInterfaceOrientation
.
这里提出的解决方案部分实现,更多信息在这里:
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)
}
}
Run Code Online (Sandbox Code Playgroud)
mik*_*eho 11
我知道这个问题适用于Swift
,但因为它是Google搜索的顶级链接之一,如果您正在寻找相同的代码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
}
Run Code Online (Sandbox Code Playgroud)
Jos*_*osh 11
简单,这适用于iOS8和9/Swift 2/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)
}
Run Code Online (Sandbox Code Playgroud)
从 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`
})
}
Run Code Online (Sandbox Code Playgroud)
在目标C中
-(void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
Run Code Online (Sandbox Code Playgroud)
在迅速
func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator)
Run Code Online (Sandbox Code Playgroud)
覆盖此方法以检测方向更改.
斯威夫特3 | 经常观察到UIDeviceOrientationDidChange通知
每次设备在3D空间中更改方向时,以下代码都会打印"deviceDidRotate" - 无论从纵向到横向的变化如何.例如,如果您将手机纵向握住并向前和向后倾斜 - 将重复调用deviceDidRotate().
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(
self,
selector: #selector(deviceDidRotate),
name: .UIDeviceOrientationDidChange,
object: nil
)
}
func deviceDidRotate() {
print("deviceDidRotate")
}
Run Code Online (Sandbox Code Playgroud)
要解决此问题,您可以保留先前的设备方向并检查deviceDidRotate()中的更改.
var previousDeviceOrientation: UIDeviceOrientation = UIDevice.current.orientation
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(
self,
selector: #selector(deviceDidRotate),
name: .UIDeviceOrientationDidChange,
object: nil
)
}
func deviceDidRotate() {
if UIDevice.current.orientation == previousDeviceOrientation { return }
previousDeviceOrientation = UIDevice.current.orientation
print("deviceDidRotate")
}
Run Code Online (Sandbox Code Playgroud)
或者,您可以使用仅在设备从横向更改为纵向时才会调用的其他通知.在这种情况下,您需要使用UIApplicationDidChangeStatusBarOrientation
通知.
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(
self,
selector: #selector(deviceDidRotate),
name: .UIApplicationDidChangeStatusBarOrientation,
object: nil
)
}
func deviceDidRotate() {
print("deviceDidRotate")
}
Run Code Online (Sandbox Code Playgroud)
我喜欢检查方向通知,因为您可以在任何类中添加此功能,而不必成为视图或视图控制器。即使在您的应用程序委托中。
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)
Run Code Online (Sandbox Code Playgroud)
比缓存通知
@objc func orientationChanged(notification : NSNotification) {
//your code there
}
Run Code Online (Sandbox Code Playgroud)
override func didRotate(from fromInterfaceOrientation: UIInterfaceOrientation) {
//swift 3
getScreenSize()
}
func getScreenSize(){
let screenWidth = UIScreen.main.bounds.width
let screenHeight = UIScreen.main.bounds.height
print("SCREEN RESOLUTION: \(screenWidth.description) x \(screenHeight.description)")
}
Run Code Online (Sandbox Code Playgroud)
如何检测Swift 3.0中的方向更改的完整工作实现.
我选择使用这个实现,因为手机的方向face up
和face down
对我来说很重要,我希望只有在我知道方向位于指定位置后才能更改视图.
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
//1
NotificationCenter.default.addObserver(self, selector: #selector(deviceOrientationDidChange), name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil)
}
deinit {
//3
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil)
}
func deviceOrientationDidChange() {
//2
switch UIDevice.current.orientation {
case .faceDown:
print("Face down")
case .faceUp:
print("Face up")
case .unknown:
print("Unknown")
case .landscapeLeft:
print("Landscape left")
case .landscapeRight:
print("Landscape right")
case .portrait:
print("Portrait")
case .portraitUpsideDown:
print("Portrait upside down")
}
}
}
Run Code Online (Sandbox Code Playgroud)
需要注意的重要事项是:
unknown
有时会出现方向.希望有人觉得这很有帮助.
小智 6
斯威夫特 4:
override func viewWillAppear(_ animated: Bool) {
NotificationCenter.default.addObserver(self, selector: #selector(deviceRotated), name: UIDevice.orientationDidChangeNotification, object: nil)
}
override func viewWillDisappear(_ animated: Bool) {
NotificationCenter.default.removeObserver(self, name: UIDevice.orientationDidChangeNotification, object: nil)
}
@objc func deviceRotated(){
if UIDevice.current.orientation.isLandscape {
//Code here
} else {
//Code here
}
}
Run Code Online (Sandbox Code Playgroud)
当需要跨各种视图控制器进行检测时,很多答案都无济于事。这个可以解决问题。
如果你想在旋转完成后做一些事情,你可以UIViewControllerTransitionCoordinator
像这样使用完成处理程序
public override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
// Hook in to the rotation animation completion handler
coordinator.animate(alongsideTransition: nil) { (_) in
// Updates to your UI...
self.tableView.reloadData()
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
140622 次 |
最近记录: |