检测应用程序是否在iOS 9中以“滑行”或“拆分视图”模式运行

2020/12/16 11:12 · ios ·  · 0评论

在iOS 9中,是否可以检测应用程序何时以iOS 9的“滑行”或“拆分视图”模式运行?

我曾尝试阅读有关iOS 9多任务处理的Apple文档,但还没有运气…

我问是因为我的应用程序中可能有一个功能,当我在Slide Over中打开该应用程序时,我想禁用该功能。

只需检查您的窗口是否占据整个屏幕即可:

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 在斯威夫特
  • UIApplication.sharedApplication.isSplitOrSlideOver 在Objective-C中

注意,在Swift中,该window对象是一个double可选的... WTF

对于iOS 13+(请注意,我自己尚未测试过iOS 13代码)

extension UIApplication {

    public var isSplitOrSlideOver: Bool {
        guard let window = self.windows.filter({ $0.isKeyWindow }).first else { return false }
        return !(window.frame.width == window.screen.bounds.width)
    }
}

我参加聚会很晚,但是如果您想要一种与方向无关的属性,请尝试以下方法:

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
    }
}

最近,我不得不确定应用程序的显示样式,不仅包括它是否更改为拆分视图或滑盖,还包括应用程序使用屏幕的哪一部分(全屏,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())
}

就像Dan Rosenstark的解决方案一样,但是更改为可以在新的iPad Pro上工作,该iPad Pro似乎报告了不同的帧和屏幕。根据它是否通过Xcode直接在设备上运行,或者是否通过TestFlight编译和发布,确定了边界高度应用商店。通过AS或TF时,高度将返回980,而不是通过Xcode希望返回1024,导致它不可能返回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)
    }
}

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

在滑动视图或33%拆分视图中时,水平尺寸类别将紧凑。我认为一旦达到50%或66%,您就无法检测到。

这是我在iPhone / iPad iOS应用程序中使用的一种没有常量的更简单,更不易碎的方法。

该代码还可以区分滑动视图和拆分视图。

为了清楚起见,我在这里返回String值,可以随意使用枚举值并合并两种全屏情况以适合您的应用。

func windowMode() -> String {
  let screenRect = UIScreen.main.bounds
  let appRect = UIApplication.shared.windows[0].bounds

  if (UIDevice.current.userInterfaceIdiom == .phone) {
    return "iPhone fullscreen"
  } else if (screenRect == appRect) {
    return "iPad fullscreen"
  } else if (appRect.size.height < screenRect.size.height) {
    return "iPad slide over"
  } else {
    return "iPad split view"
  }
}

经过大量“修补”后,我找到了适用于您的App的解决方案,该解决方案可能适合您:

在AppDelegate.swift中,创建以下变量:

var slideOverActive: Bool = false

然后,在所有视图控制器中,将UIApplicationDelegate添加到Class定义,创建一个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

}

这是一个变通办法,但目前对我有用。

快乐的足迹!

添加到@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);
}

SizeClasser基于@Michael Voccola的库编写了一个库。

您可以使用
traitCollection视图控制器的初始化它,并检测分割视图以及特定于设备的方向。

因此,您可以专门编写代码来进行1/3水平拆分视图或1/3纵向拆分视图,
UITraitCollection但这些方法无法检测到它们。
https://github.com/cemolcay/SizeClasser

尝试[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;

通过使用以下代码,您可以检查splitViewController是否折叠或不折叠

if splitViewController?.isCollapsed ?? false {
    // splitview collapsed
} else {
    // splitview not collapsed
 }

我对@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
    }
}

我参加聚会真的很晚!但是,尽管如此,这是一个简单,快速的解决方案。使用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()
}

}

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

本文地址:http://ios.askforanswer.com/jianceyingyongchengxushifouzaiios-9zhongyihuaxinghuochaifenshitumoshiyunxing.html
文章标签: ,   ,   ,  
版权声明:本文为原创文章,版权归 admin 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!