web-dev-qa-db-ja.com

iOS 9でアプリがスライドオーバーモードまたは分割表示モードで実行されているかどうかを検出する

IOS 9では、アプリがiOS 9のスライドオーバーモードまたは分割ビューモードで実行されていることを検出できますか?

IOS 9マルチタスクでAppleの documentation を読んでみましたが、これでうまくいきませんでした…

アプリをスライドオーバーで開いたときに無効にする機能がアプリにある可能性があるので、お願いします。

36
Matias Korhonen

ウィンドウが画面全体を占めるかどうかを確認するだけです。

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

これがfalseの場合、スプリットビューまたはスライドオーバーで実行しています。

回転に関係なくこのフラグを自動的に維持するコードを次に示します

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

これをすべて再パッケージ化する別の方法

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 in Swift
  • UIApplication.sharedApplication.isSplitOrSlideOver Objective-Cで

Swiftでは、windowオブジェクトは二重のオプションです... [〜#〜] wtf [〜#〜]

15
Dan Rosenstark

私はパーティーに遅れていますが、オリエンテーションとは無関係に機能するプロパティが必要な場合は、これを試してください:

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

サイズクラスについては-willTransitionToTraitCollection:withTransitionCoordinator:を、ビューのCGSizeについてはviewWillTransitionToSize:withTransitionCoordinator:の両方を見ることができます。ただし、サイズ値のハードコーディングは推奨されません。

3
stevethomp

最近、分割表示やスライドオーバーに変更された場合だけでなく、画面のどの部分がアプリケーションに使用されているか(フル、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())
}
3
Michael Voccola

水平サイズクラスは、スライドオーバーまたは33%分割ビューの場合にコンパクトになります。ただし、50%または66%に到達しても検出できないと思います。

2
jrturton

多くの「いじくり回し」の後、私はあなたのために働くかもしれない私のアプリの解決策を見つけました:

AppDelegate.Swiftで、次の変数を作成します。

var slideOverActive: Bool = false

次に、すべてのView Controllerで、IApplicationDelegateをクラス定義に追加し、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

}

ちょっとした回避策ですが、現時点ではうまく機能しています。

楽しいトレイル!

1
AT3D

Dan Rosenstarkによるソリューションと同様ですが、Xcodeを介してデバイス上で直接実行されたか、TestFlightまたはApp Store。 ASまたはTFを介した場合、Xcodeを介して好きになるはずだった1024ではなく、高さは980を返し、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)
    }
}
1
eskimo

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

@Michael Voccolaのライブラリに基づいてSizeClasserライブラリを作成しました。
View ControllerのtraitCollectionで初期化し、分割ビューとデバイス固有の向きを検出できます。
したがって、コードを1/3水平分割ビューまたは1/3縦分割ビューに具体的に記述することができますが、UITraitCollectionはそれらを検出する方法を提供しません。
https://github.com/cemolcay/SizeClasser

0
cem olcay

@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);
}
0
Sam92

そして、私は本当にパーティーに遅れています!しかし、それでもこの問題に対する簡単で迅速な解決策があります。 let width = UIScreen.mainScreen().applicationFrame.size.widthを使用して、アプリのウィンドウの幅を検出し、特定の数よりも小さいときに(つまり、iPhone画面または分割ビューで)発生させることができます。スクリーン。コンピューターに幅を何度もチェックさせるには、100秒ごとに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()
}

}

これが覗きに来る人を助けることを願っています!

0
owlswipe