UIViewの階層構造を解析


これはちょっとグレーな話題です。UIViewのsubViewメソッドを実行すると、そのView内に含まれているViewの一覧を取得できます。再帰的に実行すれば、全てのViewの構造がわかります。これを使うとフレームワークに含まれている特殊なViewの中もみごとに解析できちゃいます。

SubViewをすべて表示するためのメソッド

2番目のメソッドを呼び出すと、1番目のメソッドが実行され、階層構造がコンソールに表示されます。なお、20階層以上を超える場合はエラーが発生するのでご注意下さい。

-(void)dumpSubViews: (UIView*) view depth: (int) depth{
    NSString * indent = [@"--------------------" substringToIndex:depth];
    NSLog(@"%@%@", indent, view);
    for(UIView * subView in [view subviews]){
        [self dumpSubViews:subView depth:depth + 1];
    }
}
-(void)dumpSubViews: (UIView*) view{
    [self dumpSubViews:view depth:0];
}

テスト用のコード

例によってEmpty Applicationをベースに作成しました。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.window.backgroundColor = [UIColor whiteColor];

    UIViewController * viewCtr = [[UIViewController alloc] init];
    UINavigationController * navCtr = [[UINavigationController alloc] initWithRootViewController:viewCtr];
    self.window.rootViewController = navCtr;
    viewCtr.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"info" style:UIBarButtonItemStylePlain target:nil action:nil];
   
    navCtr.navigationBar.tintColor = [UIColor redColor];   
   
    [self dumpSubViews:navCtr.navigationBar];
   
    [self.window makeKeyAndVisible];
    return YES;
}

実行結果

View内部の構造が丸裸になりました。この情報はドキュメントに記載されていないものなので、将来的に、警告無く変更される可能性があるのでご注意下さい。この手法では、ドキュメントに記載されているAPIしか使っていませんが、やってることはリバースエンジニアリングの類なので、アプリの承認に影響を及ぼす可能性があります。

2011-11-18 00:04:47.531 UIViewHack[9920:f803] <UINavigationBar: 0x6dac460; frame = (0 20; 320 44); autoresize = W; layer = <CALayer: 0x6dcddc0>>
2011-11-18 00:04:47.532 UIViewHack[9920:f803] -<UINavigationBarBackground: 0x6da4970; frame = (0 0; 320 44); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x6da51d0>> - (null)
2011-11-18 00:04:47.533 UIViewHack[9920:f803] -<UINavigationItemView: 0x6dafcb0; frame = (160 21; 0 0); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x6dad340>>
2011-11-18 00:04:47.533 UIViewHack[9920:f803] -<UINavigationButton: 0x6dbe410; frame = (267 7; 48 30); opaque = NO; layer = <CALayer: 0x6dbbb30>>
2011-11-18 00:04:47.534 UIViewHack[9920:f803] --<UIButtonLabel: 0x6dbf730; frame = (0 0; 0 0); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x6dc0990>>

Comments

comments

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です