ObjecTips

Swift & Objective-C で iOS とか macOS とか

Share Extension の NavigationItem をカスタマイズする

Share Extension のテンプレートで作成される SLComposeServiceViewController のサブクラスを自前のコントローラクラスとして、コード内では self として説明する。

Share Extension のデフォルトの表示が以下

f:id:Koze:20150528233026p:plain

self.title = @"Title";

これで NavigationBar の title をカスタマイズできる。

f:id:Koze:20150528233513p:plain

これは 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 のカスタマイズはうまくいかない。

結果は以下のようになる。

f:id:Koze:20150528234554p:plain

まったくカスタマイズされていない。

なぜかと言うと、通常の構成であれば NavigationController の viewControllers に自前のクラスが入っている。つまり NavigationController の rootViewController が自前の ViewController クラスになる。
ところが SLComposeServiceViewController の場合はこの構成が違っていて、まず Private なクラスの SLSheetNavigationController がいて、その viewControllers の中身として Private なクラスの SLSheetRootViewController が設定されている。
自前の MyShareViewController は NavigationController の viewControllers に含まれておらず、SLSheetRootViewController クラスによって管理されている構成になっている。
(その上で title プロパティと navigationController プロパティについてはちゃんと SLComposeServiceViewController までアクセスが伝播するよう内部で実装されている)

NavigationController の NavigationItem をカスタマイズするには、この SLSheetRootViewController 経由で navigationItem にアクセスすると良い。

以下の様な結果になる。

f:id:Koze:20150529000312p:plain

左上の leftBarButtonItem、右上の rightBarButtonItem、中央の titleView 全てがカスタマイズできている。
SLComposeServiceViewController によって提供されるシステム標準のUIを使用する場合、左上のキャンセルボタンと右上の投稿ボタンの挙動を変えたり文言を変えたりするのはあまり行儀が良くないかも知れないが、中央の titleView ぐらいであれば許容範囲に思える。
また、navigationItem の leftBarButtonItems rightBarButtonItems を用いて標準のボタンに追加して独自のボタンを追加するのもいいかも知れない。