6

@"statusBarHidden"プロパティを監視し、-[UIApplication sharedApplication]それに応じてビューのサイズを調整するルートビューコントローラーにコードがあります。

これを行うと、KVO 通知が発生します。

[[UIApplication sharedApplication] setStatusBarHidden:YES]

しかし、これを行うと、KVO 通知は発生しません。

[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide]

ステータス バーが再表示されたときにビューのサイズを変更する必要がありますが、後者のメソッドを呼び出すサードパーティ API を使用しています。

これを処理する最良の方法は何ですか?

4

4 に答える 4

3

バックグラウンド

通知の発火にこの不一致が見られる理由に関しては、おそらくKVOの動作に関係しています。プロパティの値を観察します。この場合、statusBarHidden。ただし、通知を受け取るには、そのプロパティが存在するセッターを介して変更されている必要があります。

通知は魔法のように発生することはないため、セッターの副作用として効果的にコーディングする必要があります。(これは、プロパティをコーディングするときに自動的に行われることがよくあります)ただし、そのプロパティを持つクラスは、ivarを直接変更することもできます。この場合、次のようUIApplicationな内部構造体_applicationFlagsがあります。

    unsigned int statusBarHidden:1;

したがって、setStatusBarHidden:withAnimation:基礎となるデータメンバーを直接変更するだけで、オブザーバーをコールバックするために必要なセッターをバイパスすることは完全に可能です。

解決?

回避策として、このアプリがアプリストア用であるかどうかについては言及していません(個人/趣味の目的であるか、エンタープライズアプリであるか、脱獄アプリである可能性があります)。

オプションになる可能性のあることの1つは、メソッドswizzlingを使用して、のデフォルトの実装をsetStatusBarHidden:withAnimation:独自の実装に置き換えることです。独自の実装ではsetStatusBarHidden:、を呼び出すだけで、KVOが再度有効になります。または、アニメーションを保持したい場合は、GCDを使用して、アニメーションの終了setStatusBarHidden:にかかる時間の後に実行するようにスケジュールすることができますsetStatusBarHidden:withAnimation:。そうすれば、アニメーションを取得でき、を呼び出すことでKVOをトリガーすることもできますsetStatusBarHidden:

メソッドのスウィズリングがAppStoreアプリで常に拒否されるかどうかは私にはわかりません。私はそれが(少なくともiOSフレームワークのメソッドをスウィズリングするとき)そうだと思ったが、これによれば、それは許可されているか、すり抜けることができる

次の質問は、 「メソッドのスウィズリングが、パブリックAPIに含まれているにもかかわらず、Appleが本当に避けてほしいものである場合、それを回避する方法はありますか?」です。

私がリンクしたStackOverflowの質問の人々が嘘をついていない限り、それはレビューを通過しているように見えます(少なくとも時々)。したがって、自動化された方法でテストされていない可能性があります。たぶんそれは、標準機能が異なって機能しているのを見る人間のテスターに​​よって視覚的に認識されることがあります。彼らが推測する方法は、メソッドのスウィズリングの結果であるに違いありません。この場合、ステータスバーのUIの動作を変更するために実際に使用するのではなく、通知をラッチするだけなので、気にしないでください。

または、既知のiOS API(スウィズリングで使用)のセレクターを検索している可能性があります。その場合、文字列から構築されたセレクターは、検出を回避するために、非常に簡単に難読化できます。

とにかく、いくつかのオプション...

于 2013-01-28T08:21:05.350 に答える
3

これに対する解決策を見つけました:

  • たとえば MyUIApplication を使用して UIApplication をサブクラス化します。
  • setStatusBarHidden:withAnimationスーパーを呼び出し、呼び出されたときに NSNotification を送信するようにオーバーライドします
  • main.m の行を次のように変更します。return UIApplicationMain(argc, argv, @"MyUIApplication", NSStringFromClass([MyAppDelegate class]));

ステータスバーの非表示状態を設定したときに送信したカスタム通知を受け取ります

于 2013-02-06T19:22:06.387 に答える
1

Or Arbel の回答に基づいて、このクラスを作成しました。このクラスは、あなたの便宜のために通知を送信します。

https://gist.github.com/hfossli/6767765

于 2013-09-30T18:10:49.367 に答える
0

frame代わりに、アプリケーションのメイン ウィンドウ (またはそのサブビューの 1 つ) を観察したり、一部のビューのlayoutSubviewsメソッドをオーバーライドしたりできます。

于 2012-12-05T19:57:53.607 に答える