iPad Techfirm Lab

One more thing…

      こんにちは!daichi1128です         

UIMenuControllerをカスタマイズする

By daichi1128

      

OS3.2からUIMenuControllerの項目をカスタマイズできるようになったのをご存知でしょうか。

UIMenuControllerとは、こんな吹き出しのことです。

3.2以前でこれをカスタマイズしようと思うと、Responderチェインに割り込んでcutを捕まえて、入れ替えて、などとなかなか手の込んだことをしなければならなかったのですが、ついに3.2でこの問題から解放されます。

使い方を紹介します。

UIMenuItem

表示項目をカスタマイズするにはUIMenuItemクラスを使います。UIMenuItemのインスタンスを作って、そのNSArrayをUIMenuControllerのmenuItemsにセットするだけです。

UIMenuItemで表示するタイトルと実行するactionを指定します。

サンプル

ビューをタップするとメニューが表示されるようにしたいと思います。
そこでTargetViewというUIMenuControllerを表示するViewを用意します。
こんな感じです。

TargetView.h

#import <UIKit/UIKit.h>
@interface TargetView : UIView {

}
@end

TargetView.m

#import "TargetView.h"

@implementation TargetView

- (id)initWithFrame:(CGRect)frame {
    if ((self = [super initWithFrame:frame])) {
    }
    return self;
}

- (void)dealloc {
    [super dealloc];
}

- (BOOL)canBecomeFirstResponder {
	return YES;
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
	NSLog(@"touch");
	UIMenuController *menu = [UIMenuController sharedMenuController];
	[menu setTargetRect:CGRectZero inView:self];
	menu.arrowDirection = UIMenuControllerArrowRight;

	UIMenuItem *rt = [[[UIMenuItem alloc] initWithTitle:@"RT" action:@selector(rt:)] autorelease];
	UIMenuItem *reply = [[[UIMenuItem alloc] initWithTitle:@"Reply" action:@selector(reply:)] autorelease];

	menu.menuItems = [NSArray arrayWithObjects:rt, reply, nil];
	[menu setMenuVisible:YES animated:YES];
}

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
	if (action == @selector(rt:) || action == @selector(reply:)) {
		return YES;
	}
	return NO;
}

- (void)rt:(id)sender {
	NSLog(@"rt");
}

- (void)reply:(id)sender {
	NSLog(@"reply");
}

@end

このViewを呼び出す側はこんな感じです。

- (void)viewDidLoad {
    [super viewDidLoad];
	TargetView *target = [[[TargetView alloc] initWithFrame:CGRectMake(x, y, size, size)] autorelease];
	target.backgroundColor = [UIColor greenColor];
	[self.view addSubview:target];
	[target becomeFirstResponder];
}

firstResponderにしている所がポイントです。

メニューを表示する

初めてUIMenuControllerを使おうとする時けっこうメニューが表示できずハマります。

表示に必要なことは、

  • viewがfirstResponderになっていること
  • UIMenuControllerのTargetRectが設定されてること
  • その上でUIMenuControllerがvisibleになっていること

です。

まずviewをfirstResponderにするために、TargetViewのcanBecomeFirstResponderメソッドでYESを返しています。これにより、becomeFirstResponderとした時にfirstResponderになることができます。

次にUIMenuControllerのsharedMenuControllerでインスタンスを取得し、setTargetRect:inViewでメニューを表示する場所を指定しています。
ここでは手抜きして、CGRectZeroとしているので、inView(self)の左上にメニューが表示されるようになります。

最後に、setMenuVisibleをYESとして、画面に表示しています。

この間に、UIMenuItemを使ってカスタム項目を設定してます。タイトルとactionを指定してUIMenuItemを生成し、NSArrayとしてmenuItemsにセット。
タイトルが表示される文字列で、actionは実行されるメソッドです。

ここまでが、表示するためにやっていることです。

ちなみに、menuのarrowDirectionで吹き出し元をどの方向にするかを指定できます。

項目の表示制御

このまま実行すると、メニューは表示されますが、カスタム項目は表示されません。デフォルトのaction達がずらずらっと表示されてしまいます。

これを制御するのが、canPerformAction:withSenderメソッドです。
上のサンプルでは、actionがrt:とreply:ならばYESを、そうでなければNOを返すようにしています。
有効にしたいactionでYESを返せば、そのアクションに対応するタイトルが表示されるようになります。

メニューを押された時の制御

後は、actionに指定したメソッドを定義するだけです。
- (void)rt:(id)sender
などがメニューを押された時に呼ばれるようになります。

Category: iPad

Tagged:

このエントリをはてなブックマークに追加このエントリをdel.icio.usに追加このエントリをLivedoor Clipに追加このエントリをYahoo!ブックマークに追加このエントリをFC2ブックマークに追加このエントリをNifty Clipに追加このエントリをPOOKMARK. Airlinesに追加このエントリをBuzzurl(バザール)に追加このエントリをChoixに追加このエントリをnewsingに追加

4 Tweets

5 Responses

Leave a Reply

Additional comments powered by BackType

カレンダー

2012年5月
« 11月    
 123456
78910111213
14151617181920
21222324252627
28293031  

人気エントリー