it-swarm.com.de

Ermitteln Sie, ob die App in iOS 9 im Modus "Slide Over" oder "Split View" ausgeführt wird

Kann in iOS 9 erkannt werden, wann eine App im Slide Over- oder Split View-Modus von iOS 9 ausgeführt wird?

Ich habe versucht, Apples Dokumentation auf iOS 9 Multitasking durchzulesen, hatte aber kein Glück mit diesem…

Ich frage, weil ich möglicherweise eine Funktion in meiner App habe, die ich deaktivieren möchte, wenn die App in einem Slide Over geöffnet wird.

34
Matias Korhonen

Prüfen Sie einfach, ob Ihr Fenster den gesamten Bildschirm einnimmt:

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

Wenn dies nicht zutrifft, werden Sie in einer geteilten Ansicht oder einer Folie darüber ausgeführt. 

Hier wird der Code abgeschnitten, der dieses Flag unabhängig von der Rotation automatisch beibehält

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

Nur eine weitere Möglichkeit, all dies neu zu verpacken 

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

dann kannst du einfach 

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

Beachten Sie, dass das Objekt window in Swift ein optionales doppeltes Objekt ist ... WTF !

14
Dan Rosenstark

Ich bin zu spät zur Party, aber wenn Sie eine Eigenschaft wünschen, die unabhängig von der Ausrichtung funktioniert, versuchen Sie es mit dieser:

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

Sie können sowohl -willTransitionToTraitCollection: withTransitionCoordinator: für die Größenklasse als auch viewWillTransitionToSize: withTransitionCoordinator: für die CGSize Ihrer Ansicht anzeigen. Hardcoding in Größenwerten wird jedoch nicht empfohlen.

3
stevethomp

Ich musste vor kurzem den Anzeigestil einer Anwendung bestimmen, einschließlich, nicht nur, wenn sie in geteilte Ansicht oder Überstreichung geändert wurde, sondern auch, welcher Teil des Bildschirms für die Anwendung verwendet wurde (full, 1/3, 1/2, 2/3). Das Hinzufügen zu einer ViewController-Unterklasse konnte das Problem lösen. 

/// 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())
}
3
Michael Voccola

Die horizontale Größenklasse ist kompakt, wenn Sie in der Über- oder 33% -Aufteilungsansicht arbeiten. Ich glaube nicht, dass Sie es erkennen können, sobald Sie 50% oder 66% erreicht haben. 

2
jrturton

Nach langem "Basteln" habe ich eine Lösung für meine App gefunden, die für Sie funktionieren könnte:

Erstellen Sie in AppDelegate.Swift die folgende Variable:

var slideOverActive: Bool = false

Fügen Sie dann in ALLEN View Controllern UIApplicationDelegate zur Klassendefinition hinzu, erstellen Sie eine appDelegate - Variable und fügen Sie anschließend die folgende traitCollectionDidChange - Funktion hinzu:

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

                }
            }
        }
    }

}

Wo immer Sie in Ihrem Code prüfen möchten, ob der Überschlag aktiv ist oder nicht, prüfen Sie einfach:

if appDelegate.slideOverActive == true {

    // DO THIS

} else {

    // DO THIS

}

Es ist ein bisschen ein Workaround, aber im Moment funktioniert es für mich.

Glückliche Wege!

1
AT3D

Wie die Lösung von Dan Rosenstark, die jedoch geändert wurde, um auf dem neuen iPad Pro zu funktionieren, das anscheinend einen anderen Frame und eine andere screen.bounds-Höhe angibt, je nachdem, ob es direkt auf dem Gerät durch Xcode ausgeführt wird oder ob es durch TestFlight oder kompiliert und freigegeben wird Appstore. Die Höhe würde 980 zurückkehren, wenn sie durch AS oder TF statt über 1024, wie es durch Xcode gewünscht wird, verursacht wird, was es unmöglich macht, wahr zurückzukehren.

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

Die einzige funktionierende Lösung war [UIScreen mainScreen] .bounds, Self.window.screen.bounds, Self.window.frame, UIApplication.sharedApplication.keyWindow.frame usw.

CGRect frame = [UIScreen mainScreen].applicationFrame;

Was ich so fixiert habe

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;
0
FunkyKat

Ich habe eine SizeClasser-Bibliothek geschrieben, die auf @Michael Voccolas Bibliothek basiert.
Sie können es mit der Variable traitCollection Ihres View-Controllers initialisieren und geteilte Ansichten sowie die gerätespezifische Ausrichtung erkennen.
Sie könnten also Ihren Code spezifisch in eine 1/3 horizontale Teilansicht oder eine 1/3 Hochformat-Teilansicht schreiben, die mit UITraitCollection nicht erkannt werden kann.
https://github.com/cemolcay/SizeClasser

0
cem olcay

Hinzufügen zu @ Tamas's Antwort:
Hier ist der Code-Ausschnitt, der dieses Flag unabhängig von der Rotation automatisch beibehält.

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

Und ich bin wirklich zu spät zur Party! Aber hier ist eine einfache, schnelle Lösung für das Problem. Mit let width = UIScreen.mainScreen().applicationFrame.size.width können wir die Breite des Fensters meiner App ermitteln. Wenn diese Zahl kleiner als eine bestimmte Anzahl ist (z. B. auf dem iPhone-Bildschirm oder in der geteilten Ansicht), kann dies geschehen, um verschiedene Dinge auf kleineren Bildschirmen zu ermöglichen. Damit der Computer die Breite immer und immer wieder überprüfen kann, können wir jede hundertstel Sekunde einen NSTimer ausführen und dann Sachen machen, wenn die Breite höher/niedriger als etwas ist.

Einige Messungen für Sie (Sie müssen entscheiden, welche Breite, um das Material oben/unten erscheinen zu lassen): IPhone 6S Plus: 414.0mm
iPhone 6S: 375,0 mm
iPhone 5S: 320,0 mm
iPad (Hochformat): 768,0 mm
iPad (1/3 geteilte Ansicht): 320,0 mm
iPad Air 2 (1/2 Split-Ansicht): 507,0 mm
iPad (Querformat): 1024,0 mm 

Hier ist ein Code-Snippet:

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

}

Ich hoffe, das kann jedem helfen, der späht!

0
owlswipe