7128


UnityのPluginを用いて、  
iOSのステータスバーを動的に表示・非表示にさせたいのですが  
Unityからコールされた*.mや*.mmファイルからどのようにして  
UntyのViewControllerのステータスバーにアクセスしたら良いかがわかりません。

ヒントでも構いませんので知見をお持ちでしたら教えてください。


CC BY-SA 3.0
2015-02-25T15:51:55.363
7091
2015-02-26T13:05:12.523
5261
question
ios objective-c unity3d
iOSのステータスバーを動的変更(Unityプラグイン使用)


  * iOS8.1.3
  * Unity4.6.1p4

の環境で以下の手法で変更できることを確認しました。  
しかしながら対象部分のソースコードには `we do not support changing styles from script, so we need
read info.plist only once` と書かれているので変更した結果何が起きるかはわかりません。

  * `Assets/Plugins/iOS/bridge.h`

* * *
[code]

    #import <UIKit/UIKit.h>
    
    // ViewController を取得する関数
    typedef UIViewController*(^sample_get_view_controller_func)(void);
    
    #ifdef __cplusplus
    extern "C" {
    #endif /* __cplusplus */
        // Unity の ViewController を取得する関数を登録
        void sample_set_get_root_view_controller_func(sample_get_view_controller_func f);
    
    #ifdef __cplusplus
    }
    #endif /* __cplusplus */
    
[/code]

  * `Assets/Plugins/iOS/bridge.m`

* * *
[code]

    #import <UIKit/UIKit.h>
    #import "bridge.h"
    
    static sample_get_view_controller_func s_get_view_controller_func;
    
    void sample_set_get_root_view_controller(sample_get_view_controller_func f)
    {
        s_get_view_controller_func = [f copy];
    }
    
    // Unity から呼び出す関数
    void sample_update_status_bar_(int is_show)
    {
        if(s_get_view_controller_func != NULL) {
            UIViewController* vc = s_get_view_controller_func();
            if(vc != nil){
                // is_show を使用して表示フラグを変更
                ...
                [vc setNeedsStatusBarAppearanceUpdate];    // ステータスバーの更新。
                                                           // 結果後で修正する PrefersStatusBarHidden_DefaultImpl が呼び出される。
            }
        }
    }
    
[/code]

上記で定義した `sample_update_status_bar_` を Unity から呼び出せる状態にして Xcode プロジェクトを出力します。

  * 出力した xcode プロジェクトの `UnityAppController.mm`

* * *
[code]

    #include "../Libraries/bridge.h"
    ...
    - (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
    {
        // Unity の ViewController にアクセスできる関数を登録
        __unsafe_unretained typeof(self) wself = self;
        sample_set_get_root_view_controller_func(^UIViewController*(){
            return wself.rootViewController;
        });
        ...
    
[/code]

  * 出力した xcode プロジェクトの `UnityViewControllerBase.mm`

* * *
[code]

    BOOL
    PrefersStatusBarHidden_DefaultImpl(id self_, SEL _cmd)
    {
        // 既存の処理は info.plist からステータスバーの表示/非表示を制限するようになっているので
        // 全部コメントアウトする。
        //  // we do not support changing styles from script, so we need read info.plist only once
        //  static BOOL _PrefersStatusBarHidden = YES;
        //
        //  static bool _PrefersStatusBarHiddenInited = false;
        //  if(!_PrefersStatusBarHiddenInited)
        //  {
        //      NSNumber* hidden = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"UIStatusBarHidden"];
        //      _PrefersStatusBarHidden = hidden ? [hidden boolValue] : YES;
        //
        //      _PrefersStatusBarHiddenInited = true;
        //  }
        //
        //  return _PrefersStatusBarHidden;
    
        // とりあえず例として、呼び出すたびに表示/非表示が切り替わるよう
        // 例えば `sample_update_status_bar_` で取得する値を使用するように
        // 処理に変更すれば、Unity 上から好きなタイミングで制御できる
        static BOOL hidden = YES;
        hidden = !hidden;
        return hidden;
    }
    
[/code]


CC BY-SA 3.0
2015-02-26T07:14:20.160
7128
2015-02-26T07:14:20.160
5106
7091
answer


文字数足りなかったので回答に書きます、  
下記サイトを参考に実装したところUnityのプラグイン経由で  
ステータスバーOn・Offできましたので共有いたします。  
<http://blog.doinet.co.jp/?eid=1031808>

UnityViewControllerBase.mm

[code]

    // ステータスバーの非表示
    - (BOOL)prefersStatusBarHidden
    {
        return self.view.tag == 999 ? NO:YES;//NOのとき非表示となる
    }
    
    
    //- (BOOL)prefersStatusBarHidden
    //{
    //  static bool _PrefersStatusBarHidden = true;
    //
    //  static bool _PrefersStatusBarHiddenInited = false;
    //  if(!_PrefersStatusBarHiddenInited)
    //  {
    //      NSNumber* hidden = [[[NSBundle mainBundle] infoDictionary]     objectForKey:@"UIStatusBarHidden"];
    //      _PrefersStatusBarHidden = hidden ? [hidden boolValue] : YES;
    //
    //      _PrefersStatusBarHiddenInited = true;
    //  }
    //  return _PrefersStatusBarHidden;
    //}
    
[/code]

Plugin/iOS 直下に置く自作のソース

statusbar.m

[code]

    #import <Foundation/Foundation.h>
    #import <UIKit/UIKit.h>
    //#include "iPhone_View.h"
    
    extern UIViewController* UnityGetGLViewController();
    
    //extern "C" void StatusBarOn()
    void StatusBarOn()
    {
        UIViewController* parent = UnityGetGLViewController();
        parent.view.tag = 999;
        [parent setNeedsStatusBarAppearanceUpdate];
    }
    
    //extern "C" void StatusBarOff()
    void StatusBarOff()
    {
        UIViewController* parent = UnityGetGLViewController();
        parent.view.tag = 0;
        [parent setNeedsStatusBarAppearanceUpdate];    
    }
    
[/code]


CC BY-SA 3.0
2015-02-26T13:05:12.523
7153
2015-02-26T13:05:12.523
5261
7091
answer