检测应用是否在iOS 9的“幻灯片放映”或“分屏视图”模式下运行

在iOS 9中,是否有可能检测到应用程序在iOS 9的“幻灯片放映”或“拆分视图”模式下运行?

我已经尝试通过苹果公司的iOS 9多任务处理文档阅读,但没有任何运气与此…

我问,因为我可能在我的应用程序中有一个function,我想要在滑动打开应用程序时禁用它。

只要检查你的窗口是否占据整个屏幕:

BOOL isRunningInFullScreen = CGRectEqualToRect([UIApplication sharedApplication].delegate.window.frame, [UIApplication sharedApplication].delegate.window.screen.bounds); 

如果这是错误的,那么你正在分割视图或幻灯片中运行。

这里是代码剪切,将自动保持这个标志,而不论旋转

 -(void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection { // simply create a property of 'BOOL' type isRunningInFullScreen = CGRectEqualToRect([UIApplication sharedApplication].delegate.window.frame, [UIApplication sharedApplication].delegate.window.screen.bounds); } 

只是另一种方式重新包装所有这一切

 extension UIApplication { public var isSplitOrSlideOver: Bool { guard let w = self.delegate?.window, let window = w else { return false } return !window.frame.equalTo(window.screen.bounds) } } 

那么你可以

  • UIApplication.shared.isSplitOrSlideOver在Swift中
  • UIApplication.sharedApplication.isSplitOrSlideOver在Objective-C中

请注意,在Swift中, window对象是一个可选的… WTF !

我迟到了,但是如果你想要一个独立于方向的财产,试试这个:

 extension UIApplication { func isRunningInFullScreen() -> Bool { if let w = self.keyWindow { let maxScreenSize = max(UIScreen.mainScreen().bounds.size.width, UIScreen.mainScreen().bounds.size.height) let minScreenSize = min(UIScreen.mainScreen().bounds.size.width, UIScreen.mainScreen().bounds.size.height) let maxAppSize = max(w.bounds.size.width, w.bounds.size.height) let minAppSize = min(w.bounds.size.width, w.bounds.size.height) return maxScreenSize == maxAppSize && minScreenSize == minAppSize } return true } } 

您可以同时观看-willTransitionToTraitCollection:withTransitionCoordinator:对于大小类和viewWillTransitionToSize:withTransitionCoordinator:对于视图的CGSize。 大小值的硬编码不build议。

在幻灯片放映或33%分割视图时,水平尺寸类别将变得紧凑。 我认为一旦你达到50%或66%,你不会觉察。

经过多次“修补”之后,我find了适用于您的应用程序的解决scheme:

在AppDelegate.swift中,创build以下variables:

 var slideOverActive: Bool = false 

然后,在所有视图控制器中,将UIApplicationDelegate添加到类定义中,创build一个appDelegatevariables,然后添加下面的traitCollectionDidChange函数:

 class myViewController: UIViewController, UIApplicationDelegate { var appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate override func traitCollectionDidChange(previousTraitCollection: UITraitCollection?) { let screenWidth = UIScreen.mainScreen().bounds.width if previousTraitCollection != nil { let horizontalSizeClass: Int = previousTraitCollection!.horizontalSizeClass.rawValue if screenWidth == 1024 || screenWidth == 768 { // iPad if horizontalSizeClass == 2 { // Slide Over is ACTIVE! appDelegate.slideOverActive = true } else { appDelegate.slideOverActive = false } } } } } 

然后,无论您在代码中何处想检查滑动是否激活,只需检查:

 if appDelegate.slideOverActive == true { // DO THIS } else { // DO THIS } 

这是一个解决方法,但目前对我来说很有用。

快乐的小道!

我真的很晚参加派对! 但是,这是一个简单,快速的解决scheme。 使用let width = UIScreen.mainScreen().applicationFrame.size.width我们可以检测到我的应用程序的窗口的宽度,然后当它小于一定的数字(即在iPhone屏幕上或分割视图中)让更小的屏幕上发生不同的事情。 为了让电脑反复检查宽度,我们可以每隔一秒钟运行一次NSTimer,如果宽度高于/低于某个值,则执行该操作。

对于你的一些测量(你必须决定什么样的宽度会发生在上面/下面):iPhone 6S Plus:414.0mm
iPhone 6S:375.0毫米
iPhone 5S:320.0mm
iPad(人像):768.0mm
iPad(1/3分割视图):320.0mm
iPad Air 2(1/2分割视图):507.0mm
iPad(风景):1024.0mm

这是一个代码片段:

 class ViewController: UIViewController { var widthtimer = NSTimer() func checkwidth() { var width = UIScreen.mainScreen().applicationFrame.size.width if width < 507 { // The code inside this if statement will occur if the width is below 507.0mm (on portrait iPhones and in iPad 1/3 split view only). Use the measurements provided in the Stack Overflow answer above to determine at what width to have this occur. // do the thing that happens in split view textlabel.hidden = false } else if width > 506 { // undo the thing that happens in split view when return to full-screen textlabel.hidden = true } } override func viewDidAppear(animated: Bool) { widthtimer = NSTimer.scheduledTimerWithTimeInterval(0.01, target: self, selector: "checkwidth", userInfo: nil, repeats: true) // runs every hundredth of a second to call the checkwidth function, to check the width of the window. } override func viewDidDisappear(animated: Bool) { widthtimer.invalidate() } } 

我希望这可以帮助任何人偷看!

我最近不得不确定应用程序的显示风格,不仅仅是如果它改变为拆分视图或滑动,还包括屏幕的哪一部分被用于应用程序(全部,1/3,1/2, 2/3)。 把它添加到一个ViewController子类是能够解决这个问题。

 /// Dismisses this ViewController with animation from a modal state. func dismissFormSheet () { dismissViewControllerAnimated(true, completion: nil) } private func deviceOrientation () -> UIDeviceOrientation { return UIDevice.currentDevice().orientation } private func getScreenSize () -> (description:String, size:CGRect) { let size = UIScreen.mainScreen().bounds let str = "SCREEN SIZE:\nwidth: \(size.width)\nheight: \(size.height)" return (str, size) } private func getApplicationSize () -> (description:String, size:CGRect) { let size = UIApplication.sharedApplication().windows[0].bounds let str = "\n\nAPPLICATION SIZE:\nwidth: \(size.width)\nheight: \(size.height)" return (str, size) } func respondToSizeChange (layoutStyle:LayoutStyle) { // Respond accordingly to the change in size. } enum LayoutStyle: String { case iPadFullscreen = "iPad Full Screen" case iPadHalfScreen = "iPad 1/2 Screen" case iPadTwoThirdScreeen = "iPad 2/3 Screen" case iPadOneThirdScreen = "iPad 1/3 Screen" case iPhoneFullScreen = "iPhone" } private func determineLayout () -> LayoutStyle { if UIDevice.currentDevice().userInterfaceIdiom == .Phone { return .iPhoneFullScreen } let screenSize = getScreenSize().size let appSize = getApplicationSize().size let screenWidth = screenSize.width let appWidth = appSize.width if screenSize == appSize { return .iPadFullscreen } // Set a range in case there is some mathematical inconsistency or other outside influence that results in the application width being less than exactly 1/3, 1/2 or 2/3. let lowRange = screenWidth - 15 let highRange = screenWidth + 15 if lowRange / 2 <= appWidth && appWidth <= highRange / 2 { return .iPadHalfScreen } else if appWidth <= highRange / 3 { return .iPadOneThirdScreen } else { return .iPadTwoThirdScreeen } } override func traitCollectionDidChange(previousTraitCollection: UITraitCollection?) { super.traitCollectionDidChange(previousTraitCollection) respondToSizeChange(determineLayout()) } 

添加到@ Tamas的答案:
这里是代码片段,将自动保持这个标志,不论旋转。

  -(void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection { // simply create a property of 'BOOL' type isRunningInFullScreen = CGRectEqualToRect([UIApplication sharedApplication].delegate.window.frame, [UIApplication sharedApplication].delegate.window.screen.bounds); } 

我写了一个基于@Michael Voccola的库的SizeClasser库。
您可以使用视图控制器的traitCollection进行初始化,并检测拆分视图以及设备特定的方向。
所以你可以写你的代码特别是1/3的水平拆分视图或1/3的纵向拆分视图, UITraitCollection并没有给你一个方法来检测它们。
https://github.com/cemolcay/SizeClasser