2017-03-19 16 views
0

私はビューコントローラベースのステータスバーの外観がYESに設定されたアプリケーションを持っています。私の見解の中には暗いものがあり、私の見解の中には軽いコンテンツがあり、アプリケーションには非常に複雑なView Controller階層がありますが、プレゼンテーションスタイルなどをキャプチャするモーダルビューと組み合わせた適切なメソッドをサブクラス化してオーバーライドすると完全に機能します。ビューコントローラベースのステータスバーの外観を無効にする

しかし、個人用のホットスポット/ GarageBand録音/上部のコールなどのバーのようなバーのように、特定の項目を上部(ステータスバーの後ろ)に表示する方法はグローバルです。バーの背景色のため、バーを表示しながらステータスバーの外観をオーバーライドしたい(アプリ内のどこにでも表示できるので、UIWindowをサブクラス化し、そのプレゼンテーションコードを表示してそこに直接表示する)。バーは、私のバーのテキストが白で背景が暗いので、軽いコンテンツのステータスバーが表示された画面と同じように表示されますが、暗い内容のステータスバーではひどく見えます(また、バーの色を変更できません)。

「現在表示されているビューコントローラがどんなものであっても、すべてのビューコントローラのステータスバーメソッドのすべてのインスタンスをトラバースすることなく、グローバルに表示することができます。ステータスバーの外観?私のアプリはiOS 8.0+をターゲットにしています。

答えて

0

私は非常にハッキーな(しかし働く)方法で終わった。それはすべてのシナリオでうまくいかないかもしれませんが、それは私の中で働いていました。私はそのままの状態でビューを保持し、単一のビューまたはコントローラには触れていません。

まず、現在表示されている最上位のビューコントローラがあります。私はiPhone -- How to find topmost view controllerからのコードを使用して、それは少しもナビゲーションコントローラとタブバーコントローラケースを処理するように変更しました:

+ (UIViewController*) topmostControllerForViewController:(__kindof UIViewController*)topController 
{ 
    while (topController.presentedViewController) { 
     topController = topController.presentedViewController; 
    } 
    if([topController isKindOfClass:[UINavigationController class]]){ 
     UINavigationController *navController = topController; 
     return [self topmostControllerForViewController:navController.visibleViewController]; 
    } 
    if([topController isKindOfClass:[UITabBarController class]]){ 
     UITabBarController *tabController = topController; 
     return [self topmostControllerForViewController:tabController.selectedViewController]; 
    } 
    return topController; 
} 

+ (UIViewController*) topmostController 
{ 
    __kindof UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController; 
    return [self topmostControllerForViewController:topController]; 
} 

その後、私は(viewnilある)ビューのないビューコントローラを作成しました。それは(それが移行プロセスの内部で呼ばれると、それは手遅れだとしてviewDidLoad:に入れた場合、最初の呼び出しでない仕事ん)、私は以下のコメントを追加しましたinit方法ですで:

self.modalPresentationCapturesStatusBarAppearance = YES; 
self.modalPresentationStyle = UIModalPresentationOverCurrentContext; 

このコードは、私の「ダミーを許可しましたステータスバーのアピアランスを含むすべてのプレゼンテーションコンテキストと、それが提示されたときに他のビューコントローラに何が起こるかを処理するコントローラを表示する(less)コントローラ。現在のコンテキスト上に表示されると、背面のビューコントローラはビ​​ュー階層から削除されません。私がそれをしないと、それは削除され、画面は黒色になります(私はビューがなく、前のビューコントローラーを表示したいので)。

これまでのところとても良いです。次に、私はバーを正常に表示しましたが、同時にビューコントローラーをモーダルで表示しませんでした。ビューコントローラはビ​​ューを持たず、現在のコンテキスト上に表示されていたため視覚的に表示されませんでしたが、モーダルプレゼンテーションであり、ダミービューコントローラがプレゼンテーションスタイルをキャプチャするように設定されていたため、私のアプリにステータスバーのスタイルを尋ねる私は単に私がビューコントローラメソッドで望んでいたように自分のステータスバーのスタイルを設定しました。

少し問題がありました。私が新しいView Controllerを提示したとき、システムは以前のView Controllerの上にUITransitionViewを追加しました。実際のビューがあった場合は、遷移ビューの上に表示されます。トランジションビューは完全に透明ですが、ユーザーインタラクションを有効にしてすべてのタッチイベントをキャプチャしていますので、コントローラを無効にするまではアプリケーションが応答しなくなります。タッチイベントを受け取るために以前のView Controllerが必要でした。UITransitionView以来

for (UIView *view in self.subviews) { 
     NSString *className = NSStringFromClass([view class]); 
     if([className hasPrefix:@"UIT"] && className.length == 16){ 
      //this must be UITransitionView, but I'm not using it directly since it may interfere with private API usage and get app rejected by Apple. 
      //now, we need to find another transition view inside this and remove it 
      for (UIView *innerView in view.subviews) { 
       className = NSStringFromClass([innerView class]); 
       if([className hasPrefix:@"UIT"] && className.length == 16){ 
        //this is the transition view that we need to remove 
        [innerView removeFromSuperview]; 
       } 
      } 
     } 
} 

がプライベートビュータイプであると私はもしわからない:トランジションアニメーションが完了した後、ビューコントローラを提示するとき、私は深く掘っていモーダルプレゼンテーションが遷移ビューを追加した場合、それを削除しましたそれはApp Storeで問題を引き起こします。最初の文字であるUITをチェックし、クラス名の長さをチェックすることによって、ヒューリスティックチェックUITransitionViewを実行しました。それは防弾ではないが、うまくいくと思われ、偽陽性を返す可能性は低い。

すべてが現在正常に動作しています。それはハッキーです、そして、特にモーダルプレゼンテーションがボンネットの下で変化するならば、将来的には壊れるかもしれません。しかし、安心して、それは動作します。

関連する問題