Обнаруживать, работает ли приложение в режиме "Слайд-режим" или "Сплит-просмотр" в iOS 9

В iOS 9 можно ли обнаружить, когда приложение работает в режиме ожидания IOS 9 Slide Over или Split View?

Я пробовал читать через Apple documentation в многозадачном режиме iOS 9, но мне не повезло с этим...

Я прошу, потому что у меня может быть функция в моем приложении, которую я хотел бы отключить, когда приложение будет открыто в режиме "Слайд".

Ответ 1

Просто проверьте, занимает ли ваше окно весь экран:

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

Ответ 2

Еще один способ переупаковки всех этих

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!

Ответ 3

Я опаздываю на вечеринку, но если вы хотите свойство, которое работает независимо от ориентации, попробуйте следующее:

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

Ответ 4

Вы можете посмотреть как -willTransitionToTraitCollection: withTransitionCoordinator: для класса size и viewWillTransitionToSize: withTransitionCoordinator: для CGSize вашего представления. Однако значения жесткого кодирования в размерах не рекомендуются.

Ответ 5

Класс горизонтального размера будет компактным, если в режиме слайда или 33% с разметкой. Я не думаю, что вы можете обнаружить, как только вы идете на 50% или 66%.

Ответ 6

После долгих "мастерингов" я нашел решение для своего приложения, которое может сработать для вас:

В AppDelegate.swift создайте следующую переменную:

var slideOverActive: Bool = false

Затем во ВСЕХ ваших контроллеров представлений добавьте UIApplicationDelegate в определение класса, создайте переменную appDelegate, а затем добавьте ниже traitCollectionDidChange strong > :

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

И я очень опаздываю на вечеринку! Но, тем не менее, здесь простое, экономное решение проблемы. Используя 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,0 мм
iPad Air 2 (1/2 сплит-вид): 507.0mm
iPad (пейзаж): 1024,0 мм

Здесь фрагмент кода:

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

}

Я надеюсь, что это поможет любому, кто заглянет!

Ответ 8

Недавно мне пришлось определять стиль отображения приложения, в том числе, не только в том случае, если он был изменен для разделения или слайдов, но и какая часть экрана использовалась для приложения (полный, 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())
}

Ответ 9

Добавление в ответ @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);
}

Ответ 10

Я написал библиотеку SizeClasser, основанную на библиотеке @Michael Voccola.
Вы можете инициализировать его с помощью traitCollection вашего контроллера вида и обнаруживать разделенные виды, а также ориентацию устройства.
Таким образом, вы можете написать свой код в виде 1/3 горизонтального разделения или 1/3 портретного просмотра, который UITraitCollection не дает вам способ их обнаружить.
https://github.com/cemolcay/SizeClasser