問題タブ [uikit-state-preservation]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票する
2 に答える
1748 参照

ios - UICollectionView 状態の復元: スクロール位置のカスタマイズ

要素が移動する可能性のある UICollectionView の状態の復元を処理する最良の方法を見つけようとしています。私の目標は、アイテムが移動した場合でも、アプリを再起動したときに、コレクション ビューで最後に表示されたアイテムが引き続き表示されるようにすることです。たとえば、アイテム A は、アプリが強制終了されたときにインデックス 3 のセルにあり、アイテム A をインデックス 4 に表示する必要があるとモデルが指示している場合にアプリを再起動すると、コレクション ビューでインデックス 4 のセルへのオフセットを初期化する必要があります.

ドキュメントに記載されているように、クラスにUIDataSourceModelAssociationプロトコルを実装することでこれを処理できると思いました。UICollectionViewDataSource

[UITableView および UICollectionView] クラスは、このプロトコルのメソッドを使用して、同じデータ オブジェクト (同じ行インデックスだけでなく) がスクロールされて表示され、選択されるようにします。

ただし、私が観察したことは、このプロトコルを実装すると、復元中に選択したセルの indexPath に適切に影響することですが(これは私のアプリにとって重要ではありません) 、スクロール位置には影響しません。スクロール位置 (コレクション ビューの contentOffset) は、アプリが強制終了されたときの正確な位置に常に復元され、UICollectionViewDataSource の影響を受けません。

このような回避策があります。基本的にモデル アソシエーション プロトコルと同じパターンですが、手動で行う必要があります。

UIDataSourceModelAssociation の使い方を誤解していませんか? バグはありますか?これを機能させるためのよりエレガントな、または正しい方法はありますか?

0 投票する
1 に答える
90 参照

ios8 - XCode 6 での iOS 状態の保持

アプリケーションの状態を XCode 6 と iOS 8 で保持したいと考えています。ただし、見つけることができるすべての情報は、ストーリーボードと復元識別子を参照していますが、ストーリーボードは使用していません。

Xcode 6 でビュー コントローラーの復元 ID のフィールドが見つからないようです。ビュー用のものは見つかりましたが、すべてのチュートリアルビューではなくコントローラーにタグを付ける必要があることを明確にします!

どんな助けでも大歓迎です:)

事前にThx

0 投票する
1 に答える
1148 参照

ios - タブ バーとナビゲーション コントローラー アプリでの状態の復元

目標:タブ コントローラー ベースのアプリ (各タブにナビゲーション コントローラーを使用) で状態を復元しようとしています。

問題:再起動すると、選択したタブは期待どおりに復元されているように見えますが、そのタブ内のナビゲーション階層は復元されていません。

発達:

  1. 最初はプロジェクト テンプレート「タブ ベースのアプリ」から始めました。
  2. 次に、子ビュー コントローラーとタブ バー コントローラーの両方に復元 ID を追加しました。
  3. アプリ デリゲートでは、 と を実装application(_:shouldSaveApplicationState:)application(_:shouldRestoreApplicationState:)ました。

次にアプリを実行し、2 番目 (右) のタブに切り替え、ホームをクリックして終了します。o 再起動すると、右側のタブが表示されます (期待どおり)。ここまでは順調ですね。

  1. 次に、ストーリーボードに移動し、両方の子ビュー コントローラーをそれぞれのナビゲーション コントローラーに埋め込み、それらにも復元 ID を割り当てます。

アプリを実行しましたが、復元は引き続き機能します。まだいい。

  1. 次に、「詳細」View Controller を追加します。そのクラスはUIViewController、ストーリーボードのカスタム サブクラスであり、デバッグ ラベルの内容とそのビューの背景色を構成するプロパティがあります。

  2. 各タブのトップビューコントローラーに「詳細を表示...」ボタンを配置し、それぞれから(共有)詳細ビューコントローラーへのセグエを作成しました。これで、ストーリーボードは六角形のように見えます (また、どちらのセグエにも Interface Builder で識別子が設定されています)。そのため、左右の両方のトップ ビュー コントローラーが同じタイプの「詳細」ビュー コントローラーを共有します。ショーでは、プッシュされた場所と区別できるように構成されています (次のポイントを参照)。

  3. トップ ビュー コントローラーのprepareForSegue(_:sender:)メソッドごとに、プッシュされた詳細ビュー コントローラーを異なる方法で構成します。異なるテキストと背景色 (それぞれ「左」と青、「右」と赤)。

  4. 詳細ビュー コントローラーにコードを追加して、テキストと背景色のプロパティの状態を保存および復元しましencodeRestorableStateWithCoder(_:)decodeRestorableStateWithCoder(_:)viewDidLoad()また、それらのプロパティの値をビューに反映するように実装しました。インスタンス化され、セグエを介してナビゲーションにプッシュされるたびに、プロパティが最初に設定され、次に でビューを構成するために使用されviewDidLoad()ます。復元中にインスタンス化されるたびに、プロパティが設定されdecodeRestorableStateWithCoder(_:)、 で同様に使用されviewDidLoad()ます。

...しかし、このコードを実行すると、最後に選択したタブが復元されますが、詳細ではなく、上部のビュー コントローラー(左または右)までのみです。興味深いことに、最後に詳細ビュー コントローラーに設定された背景色が一瞬点滅します。

encodeRestorableStateWithCoder(_:)とにブレークポイントを配置しdecodeRestorableStateWithCoder(_:)ましたが、実行されるのは最初の 1 つだけです ( encode )。

  1. 何が欠けているのか疑問に思ったので、先に進んでアプリ デリゲートを実装しましたapplication(_:viewControllerWithRestorationIdentifierPath:coder:)(常に nil を返しますが、渡されたパス コンポーネントをログに記録します)。

このメソッドが必要かどうかについてのドキュメントはあまり明確ではありません。いずれにせよ、詳細を除くすべてのView Controllerは、それがなくても完全に復元されるようです。最後のパス コンポーネント (つまり、そのコントローラーの復元 ID) に基づいて各ビュー コントローラーをインスタンス化し、それを返すコードを追加しました。

これでdecodeRestorableStateWithCoder(_:) 呼び出されますが、ナビゲーションはまだタブのトップ ビュー コントローラーに戻ります。

それで、何が起こっているのですか?タブ バー + ナビゲーション コントローラー アプリで状態の保存と復元を実装するには何が欠けていますか?

0 投票する
1 に答える
243 参照

ios - アプリケーションの状態の保持中に SKAction コード ブロックのエンコード制限を回避する良い方法は何ですか?

問題

ノード階層がエンコードされると、アプリケーションの状態の保存や「ゲームの保存」中によくSKActionあることですが、コード ブロックをエンコードできないため、コード ブロックでアクションを実行しているノードは特別に処理する必要があります。

例 1: アニメーション後の遅延コールバック

ここで、オークが殺されました。アニメーション化されてフェードアウトし、ノード階層から削除されます。

orc ノードがエンコードされてからデコードされた場合、アニメーションは適切に復元され、期待どおりに完了します。

ただし、この例は、フェード後に実行されるコード ブロックを使用するように変更されています。おそらく、オークが(最終的に)死んだら、コードはゲームの状態をクリーンアップします。

残念ながら、コード ブロックはエンコードされません。アプリケーションの状態の保存 (またはゲームの保存) 中に、このシーケンスが実行されている場合、警告が発行されます。

SKAction: 実行ブロック アクションを正しくエンコードできません。Objective-C ブロックは NSCoding をサポートしていません。

デコード後、オークはフェードして親から削除されますが、クリーンアップ メソッドorcDidFinishDying:は呼び出されません。

この制限を回避する最善の方法は何ですか?

例 2: トゥイーン

SKAction customActionWithDuration:actionBlock:トゥイーンに美しくフィットするようです。この種の定型コードは次のとおりです。

残念ながらcustomActionWithDuration:actionBlock:エンコードできません。アニメーション中にゲームが保存されると、ゲームのロード時に正しく復元されません。

繰り返しますが、この制限を回避する最善の方法は何ですか?

不完全なソリューション

ここに私が検討したが気に入らない解決策があります。(そうは言っても、これらのいずれかをうまく擁護する回答を読みたいです。)

  • 不完全な解決策:アニメーションではperformSelector:onTarget:なく使用します。runBlock:呼び出されたセレクターに引数を渡すことができないため、この解決策は不完全です。呼び出しのコンテキストは、ターゲットとセレクターの名前によってのみ表現できます。良くない。

  • 不完全な解決策: エンコード中に、SKAction関連するノードからシーケンスを削除し、シーケンスが完了したかのようにプログラムの状態を進めます。alpha最初の例では、ノードをすぐに に設定し0.0、orc ノードを親から削除して、 を呼び出すことを意味しますorcDidFinishDying:。これは、少なくとも 2 つの理由から残念な解決策です。1) エンコード中に特別な処理コードが必要です。2) 視覚的には、ノードはアニメーションを終了する機会を得られません。

  • SKAction不完全な解決策: エンコード中に、関連するノードからコード ブロックを削除し、デコード中にそれらを再作成します。これは自明ではありません。

  • 不完全な解決策:SKAction特に遅延の後では、コード ブロックを使用しないでください。アプリの良好な状態を復元するために、アニメーションの完了に依存しないでください。(将来のイベントをエンコード可能な方法でスケジュールする必要がある場合は、コード ブロックを使用せずに独自のイベント キューを作成してください。) この解決策は不完全です。なぜならrunBlock、 とcustomActionWithDuration:actionBlock:は非常に便利であり、恥ずべきことです (そして、初心者にとっては繰り返し起こる罠です)。 )それらを悪と見なす。

0 投票する
2 に答える
197 参照

ios - デコード後に SKAction シーケンスが再起動しないようにするにはどうすればよいですか?

私のアプリは、アプリケーションの状態の保存と復元を備えた SpriteKit ゲームです。アプリケーションの状態が保持されると、現在のノードのほとんどSKSceneがエンコードされます。

を実行しているノードSKActionがエンコードおよびデコードされると、アクションは最初から再開されます。これは標準的なSpriteKit動作のようです。

私にとって、この動作は で最も顕著ですSKAction sequence。デコード時に、そのコンポーネント アクションの数がすでに完了していても、シーケンスは再開されます。たとえば、シーケンスを実行するコードが次のようになっているとします。

アプリケーションの状態が 10 秒間の待機中に保持され、その後復元されると、SKActionシーケンスは最初から再び開始され、2 回目のフェードアウトとインが表示されます。

SKAction sequenceが他のアクションと一致するデコード動作を示すべきであることは理にかなっています。ただし、既に完了したアクションが再度実行されないように、例外を作成すると便利です。デコード後にシーケンスが再開しないようにするにはどうすればよいですか?