Share Extension の NavigationItem をカスタマイズする
Share Extension のテンプレートで作成される SLComposeServiceViewController
のサブクラスを自前のコントローラクラスとして、コード内では self
として説明する。
Share Extension のデフォルトの表示が以下
self.title = @"Title";
これで NavigationBar の title をカスタマイズできる。
これは UINavigationController
に含まれる UIViewController
のサブクラスにおいて self.title = @"Title";
を実装して NavigationBar 上のタイトルをカスタマイズするのと同様の方法で基本的なカスタマイズの方法になる。
次に
self.navigationItem.leftBarButtonItem.title = @"Button"; self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:nil action:nil]; UIImage *image = [UIImage imageNamed:@"emoji"]; UIImageView *imageView = [[UIImageView alloc] initWithImage:image]; self.navigationItem.titleView = imageView;
これで通常ならば左上の BarButtonItem はタイトルが Button
となり、右上の BarButtonItem はプラスマーク、中央のタイトル部分には指定の画像が表示されるはずになる。
ところが SLComposeServiceViewController
の場合、この実装では NavigationBar のカスタマイズはうまくいかない。
結果は以下のようになる。
まったくカスタマイズされていない。
なぜかと言うと、通常の構成であれば NavigationController の viewControllers に自前のクラスが入っている。つまり NavigationController の rootViewController が自前の ViewController クラスになる。
ところが SLComposeServiceViewController
の場合はこの構成が違っていて、まず Private なクラスの SLSheetNavigationController
がいて、その viewControllers の中身として Private なクラスの SLSheetRootViewController
が設定されている。
自前の MyShareViewController
は NavigationController の viewControllers に含まれておらず、SLSheetRootViewController
クラスによって管理されている構成になっている。
(その上で title
プロパティと navigationController
プロパティについてはちゃんと SLComposeServiceViewController
までアクセスが伝播するよう内部で実装されている)
NavigationController の NavigationItem をカスタマイズするには、この SLSheetRootViewController
経由で navigationItem にアクセスすると良い。
以下の様な結果になる。
左上の leftBarButtonItem、右上の rightBarButtonItem、中央の titleView 全てがカスタマイズできている。
SLComposeServiceViewController
によって提供されるシステム標準のUIを使用する場合、左上のキャンセルボタンと右上の投稿ボタンの挙動を変えたり文言を変えたりするのはあまり行儀が良くないかも知れないが、中央の titleView ぐらいであれば許容範囲に思える。
また、navigationItem の leftBarButtonItems
rightBarButtonItems
を用いて標準のボタンに追加して独自のボタンを追加するのもいいかも知れない。