これはいい。
使い方も簡単。UIMenuItemにイメージをセットするだけ。
UIMenuItem *cameraItem = [[UIMenuItem alloc] initWithTitle:nil action:@selector(cameraAction:)]; [cameraItem cxa_setImage:[UIImage imageNamed:@"camera"] hidesShadow:YES forTitle:NSLocalizedString(@"Camera", nil)];
実現方法は面白くて、method swizzlingを使い本来テキストを描画するdrawTextInRectを書き換えて画像描画に対応させている。
Method origMethod = class_getInstanceMethod(self, @selector(drawTextInRect:)); origDrawTextInRect = (void *)method_getImplementation(origMethod); if (!class_addMethod(self, @selector(drawTextInRect:), (IMP)newDrawTextInRect, method_getTypeEncoding(origMethod))) method_setImplementation(origMethod, (IMP)newDrawTextInRect); :
なおUIMenuItemのカテゴリとして実装してある為、画像や設定(影)をグローバル変数で持っている(NSMutableDictionary* titleImagePairs)。cxa_setImage:hidesShadow:forTitle: のタイトル文字列はこの辞書のキーとして使われている。その為、タイトル文字は表示されないが必須でかつ重複はできない(と思われる)。
コードは短くて無駄が無い。何よりもアイディアがいいと思った。
ライセンス:MIT
メモ)NSMutableDictionaryの初期化はこんな風にかけるのか。
+ (void)load { static dispatch_once_t once; dispatch_once(&once, ^{ titleImagePairs = [@{} mutableCopy]; titleHidesShadowPairs = [@{} mutableCopy]; }); }
関連)blocksベースのUIMenuItemビルダ。