在iOS 9中,是否可以检测应用程序何时在iOS 9的“幻灯片放映”或“拆分视图”模式下运行?
我已尝试通过Apple的documentation阅读iOS 9多任务处理,但对此没有任何好运......
我问,因为我的应用程序中可能有一个功能,我想在幻灯片结束时打开应用程序时禁用该功能。
答案 0 :(得分:33)
只需检查您的窗口是否占据整个屏幕:
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);
}
答案 1 :(得分:15)
重新包装所有这些
的另一种方法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
UIApplication.sharedApplication.isSplitOrSlideOver
请注意,在Swift中,window
对象是双重可选... WTF!
答案 2 :(得分:9)
我迟到了,但是如果你想要一个独立于方向工作的房产,试试这个:
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
}
}
答案 3 :(得分:3)
您可以同时观看-willTransitionToTraitCollection:withTransitionCoordinator:用于size类,viewWillTransitionToSize:withTransitionCoordinator:用于视图的CGSize。但不建议使用硬编码的大小值。
答案 4 :(得分:3)
I recently had to determine display style of an application based including, not only if it changed to split view or slide-over, but also what portion of the screen was being utilized for the application (full, 1/3, 1/2, 2/3). Adding this to a ViewController subclass was able to solve the issue.
/// 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())
}
答案 5 :(得分:2)
滑动或33%分割视图时,水平尺寸类将是紧凑的。一旦你达到50%或66%,我认为你无法察觉。
答案 6 :(得分:1)
经过多次修补后,我找到了适用于我的应用程序的解决方案:
在AppDelegate.swift中,创建以下变量:
var slideOverActive: Bool = false
然后,在所有视图控制器中,将 UIApplicationDelegate 添加到类定义,创建 appDelegate 变量,然后添加以下 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
}
这是一种解决方法,但目前它对我有用。
快乐的小道!
答案 7 :(得分:1)
类似于Dan Rosenstark的解决方案,但更改为在新的iPad Pro上工作,该iPad Pro似乎报告了不同的帧和屏幕。根据它是否通过Xcode直接在设备上运行或是否已编译并发布,限制了高度通过TestFlight或App Store。通过AS或TF时,高度将返回980,而不是Xcode希望的高度,导致高度不可能返回true。
extension UIApplication {
public var isSplitOrSlideOver: Bool {
guard let w = self.delegate?.window, let window = w else { return false }
return !(window.frame.width == window.screen.bounds.width)
}
}
答案 8 :(得分:1)
这是我在iPhone / iPad iOS应用中使用的一种没有常数的更简单,更不易碎的方法。
此代码还可以区分幻灯片和拆分视图。
为清楚起见,我在这里返回String值,可以自由使用枚举值并合并两种全屏情况以适合您的应用。
-------------------------------------
| user_id| segment_array |
-------------------------------------
| 100 | [seg1, seg3, seg4] |
| 200 | [seg3, seg4] |
| 300 | [seg1, seg2, seg5] |
-------------------------------------
答案 9 :(得分:0)
我参加派对的时间已经很晚了!但是,这是一个简单,快捷的解决方案。使用let width = UIScreen.mainScreen().applicationFrame.size.width
,我们可以检测应用程序窗口的宽度,然后在小于某个数字时(即在iPhone屏幕上或在拆分视图中)发生事情,这对于在较小的屏幕上进行不同的事情很有用。为了让计算机一遍又一遍地检查宽度,我们可以每百分之一秒运行一次NSTimer,然后在宽度高于/低于某些东西的情况下进行操作。
为您量身定做的一些测量(您必须确定在上方/下方出现的宽度):
iPhone 6S Plus:414.0mm
iPhone 6S:375.0mm
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()
}
}
我希望这可以帮助任何偷看的人!
答案 10 :(得分:0)
添加@ 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);
}
答案 11 :(得分:0)
我根据@Michael Voccola的图书馆写了一个SizeClasser
图书馆
您可以使用视图控制器的traitCollection
对其进行初始化,并检测拆分视图以及设备特定方向
因此,您可以专门编写代码1/3水平分割视图或1/3纵向分割视图UITraitCollection
无法检测到它们。
https://github.com/cemolcay/SizeClasser
答案 12 :(得分:0)
尝试[UIScreen mainScreen] .bounds, self.window.screen.bounds, self.window.frame, UIApplication.sharedApplication.keyWindow.frame等,唯一可行的解决方案是弃用方法
CGRect frame = [UIScreen mainScreen].applicationFrame;
我以这种方式修复了
CGRect frame = [UIScreen mainScreen].applicationFrame;
frame = CGRectMake(0, 0, frame.size.width + frame.origin.x, frame.size.height + frame.origin.y);
self.window.frame = frame;
答案 13 :(得分:-1)
通过使用以下代码,您可以检查splitViewController是否折叠
if splitViewController?.isCollapsed ?? false {
// splitview collapsed
} else {
// splitview not collapsed
}
答案 14 :(得分:-1)
我对@Michael Voccola解决方案进行了修改,解决了定向问题
我在这种情况下使用这种方法来检测所有iPad的分屏状态和处理布局
只需致电determineLayout()
即可获取当前的layoutStyle
private func getScreenSize() -> CGRect {
let size = UIScreen.main.bounds
return size
}
private func getApplicationSize() -> CGRect {
let size = UIApplication.shared.windows[0].bounds
return 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"
}
func determineLayout() -> LayoutStyle {
if UIDevice.current.userInterfaceIdiom == .phone {
return .iPhoneFullScreen
}
let screenSize = getScreenSize().size
let appSize = getApplicationSize().size
let screenWidth = screenSize.width
let appWidth = appSize.width
if screenSize == appSize {
// full screen
return .iPadFullscreen
}
let persent = CGFloat(appWidth / screenWidth) * 100.0
if persent <= 55.0 && persent >= 45.0 {
// The view persent between 45-55 that's mean it's half screen
return .iPadHalfScreen
} else if persent > 55.0 {
// more than 55% that's mean it's 2/3
return .iPadTwoThirdScreeen
} else {
// less than 45% it's 1/3
return .iPadOneThirdScreen
}
}