30094


Xcode8、Swift3、SpriteKitでランアクションライクなアプリを作っています。  
ポーズボタンを実装し、プレイ中に

1、ポーズボタンを押下した際と  
2、ホームボタンや電源ボタンを押下した際に

isPausedを使って障害物を停止させ、タップを禁止しています。  
同時にtimer.invalidateによって障害物を出現させるタイマーを一時停止させ、  
再開ボタンを出現させて、ゲームを再開できるようにしています。

このうち2によってポーズされた場合、アプリアイコンをタップして再開した際、障害物の動きが止まっておらず、タップもできてしまいます。タイマーは正常に停止したままで、再開ボタンも出現しています。  
また、1によってポーズされたまま、ホームに戻ってアプリを再開した場合も同様の現象が起こります。

AppDelegateからNotificationCenterによって呼び出されたprintにより、ゲームを閉じようとした時、閉じた時、開こうとした時、開いた時のいずれの時点でも
self.isPaused = true であることを確認しています。

isPausedで停止された画面をアプリの再開時に動き出さないようにするにはどうしたらよいのでしょうか。


CC BY-SA 3.0
2016-11-04T01:20:31.180
30090
2016-11-04T23:18:57.957
2016-11-04T07:31:17.723
18540
19417
question
swift xcode spritekit
ホームボタンを押下時してポーズされた画面がアプリに戻った時に解除されてしまう


[API Reference - class
SKView](https://developer.apple.com/reference/spritekit/skview)

これの、`isPaused`の項目から、一部引用します。

> Discussion
>
> When an application moves from an active to an inactive state, isPaused is
> automatically set to true. When an application returns to an active state,
> isPaused is automatically set to its previous value.

すなわち、`UIApplication`の`Notification`を利用しなくても、「automatically」に、アプリがバックグラウンドに回ったら、ポーズになって、フォアグラウンドに戻ったら、ポーズが解除されます。  
「えーっ、`SKScene`の`isPaused`は操作したけど、`SKView`の`isPaused`は操作してないよ！」とおっしゃるかもしれませんが、じっさいのアプリの挙動を見ると、連動しているのだと推測できます。

* * *

## ●第1案

なので、意図したポーズをするには、「automatically」なポーズの解除がなされた直後に、`isPaused`を`true`にするといいでしょう。では、そのタイミングはなにかというと、`.UIApplicationDidBecomeActive`というNotificationが使えそうです。

_SKSceneのサブクラス_

[code]

    override func didMove(to view: SKView) {
        NotificationCenter.default.addObserver(self, selector: #selector(becomeActive(_:)), name: .UIApplicationDidBecomeActive, object: nil)
    }
    
    func becomeActive(_ notification: Notification) {
        isPaused = true
    }
    
[/code]

* * *

## ●第2案

`SKView`のサブクラスを作成し、プロパティ`isPaused`を上書きすることを考えます。

[code]

    class SubSKView: SKView {
        override var isPaused: Bool {
            get {
                return super.isPaused
            }
            set {
                scene?.isPaused = true
            }
        }
    }
    
[/code]

プロジェクト内のすべてのソースコード、Storyboardで、`SKView`と型指定している箇所を、`SubSKView`に書き換えてください。アプリがフォアグラウンドに戻っても、ポーズしたままになります。  
なお、このままでは、複数のSceneを採用している場合、すべてのSceneにそれが適用されますし、意図しないケースでポーズしたままということになるおそれがあります。クラスの上書きには、副作用を注意すべきです。


CC BY-SA 3.0
2016-11-04T08:00:45.633
30094
2016-11-04T23:18:57.957
2016-11-04T23:18:57.957
18540
18540
30090
answer