Detect if app is running in Slide Over or Split View mode in iOS 9

Solution 1:

Just check if your window occupies the whole screen:

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

If this is false, then you're running in a split view or a slide over.

Here is the code snipped which will automatically maintain this flag irrespective of rotation

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

Solution 2:

Just another way to repackage all of this

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

then you can just

  • UIApplication.shared.isSplitOrSlideOver in Swift
  • UIApplication.sharedApplication.isSplitOrSlideOver in Objective-C

Note that, in Swift, the window object is a double optional... WTF!

For iOS 13+ (note, I haven't tested the iOS 13 code myself yet)

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

Solution 3:

I'm late to the party, but if you want a property that works independent of the orientation, try this one:

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

Solution 4:

Like the solution by Dan Rosenstark, but changed to work on the new iPad Pro's that seem to report a different frame and screen.bounds height based on if it's ran directly on the device through Xcode, or if it is compiled and released through TestFlight or App Store. The height would return 980 when through AS or TF, rather than 1024 as it was supposed to like through Xcode causing it to be impossible to return 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)
    }
}