第一次使用UIMenuController慕趴,遇見一些問題痪蝇,記錄如下。
概念
UIMenuController即菜單控制器冕房,是一個單例對象躏啰,用來復制,粘貼耙册,刪除等內(nèi)容的操作给僵。
使用步驟
通過下面三部完成UIMenuController的使用,缺一不可:
- 通過[UIMenuController sharedMenuController]來獲取實例對象详拙;
- 通過
- (void)setTargetRect:(CGRect)targetRect inView:(UIView *)targetView
設(shè)置菜單的顯示位置帝际,例如設(shè)置targetRect為下圖的紅色區(qū)域,那么菜單會顯示在targetRect上方中間位置饶辙,如果上方中間位置在屏幕上不能夠顯示蹲诀,那么會顯示在下方中間位置。如果targetRect的寬度高度設(shè)置為零弃揽,那么會在一個點顯示脯爪。(菜單會根據(jù)設(shè)置的區(qū)域自動調(diào)整位置则北,以便能全部顯示出來); - 通過
menuVisible
屬性設(shè)置為YES(或者setMenuVisible:animated:
方法)令菜單顯示出來痕慢。
使用菜單
假設(shè)點擊控制器的view顯示菜單尚揣,那么在控制的touchesBegan方法中按照上面說的三步設(shè)置UIMenuController
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
UIMenuController *menu = [UIMenuController sharedMenuController];
[menu setTargetRect:CGRectMake(100, 300, 200, 20) inView:self.view];
menu.menuVisible = YES;
}
此時我們運行程序,點擊控制的view并沒有彈出菜單掖举,原因是:
1.控制器或者UIView能夠成為first responder ,需要實現(xiàn)下面方法
- (BOOL)canBecomeFirstResponder
{
return YES;
}
2.在顯示菜單時需要設(shè)置為first responder 快骗,在touchesBegan中添加[self becomeFirstResponder];
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
[self becomeFirstResponder]; //設(shè)置為第一響應者
UIMenuController *menu = [UIMenuController sharedMenuController];
[menu setTargetRect:CGRectMake(100, 300, 200, 20) inView:self.view];
menu.menuVisible = YES;
}
3.并且需要實現(xiàn)UIResponder的canPerformAction:withSender:方法,該方法與編輯菜單相關(guān)塔次,與返回YES的方法關(guān)聯(lián)的菜單將顯示出來滨巴。
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
if (action == @selector(paste:))
{
return YES;
} else if (action == @selector(cut:))
{
return YES;
}
else{
return NO;
}
}
其中paste:
和cut:
方法都定義在UIResponderStandardEditActions協(xié)議,都是與菜單相關(guān)的俺叭。
由于只有paste:
和cut:
方法能夠響應,因此只顯示cut和paste兩個菜單泰偿,顯示效果如下
如果直接返回YES熄守,那么所有菜單都會顯示,如下圖耗跛。
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
return YES;
}
說明:如果canPerformAction:withSender: 的first responder沒有處理事件裕照,會順著響應鏈向上拋。
使用自定義菜單
可以通過UIMenuItem來自定義菜單调塌,需要設(shè)置菜單的顯示內(nèi)容以及點擊菜單的后的處理方法晋南。然后將自定義的UIMenuItem添加到UIMenuController的menuItems(一個數(shù)組)屬性中。其它使用過程與上面講解的使用菜單的過程一樣羔砾。 具體使用見下面例子负间,
添加自定義菜單
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
[self becomeFirstResponder]; //成為第一響應者
UIMenuController *menu = [UIMenuController sharedMenuController];
[menu setTargetRect:CGRectMake(100, 300, 200, 20) inView:self.view];
// 定義兩個菜單a和b
UIMenuItem *a = [[UIMenuItem alloc] initWithTitle:@"a"
action:@selector(aAction)];
UIMenuItem *b = [[UIMenuItem alloc] initWithTitle:@"b"
action:@selector(bAction)];
// 自定義菜單添加到菜單欄中
menu.menuItems = @[like,writeBack,report];
menu.menuVisible = YES;
}
實現(xiàn)aAction
和bAction
方法
- (void)aAction{
NSLog(@"--aAction--")
}
- (void)bAction{
NSLog(@"--bAction--")
}
控制器或者UIView能夠成為first responder
- (BOOL)canBecomeFirstResponder
{
return YES;
}
實現(xiàn)canPerformAction:withSender:方法
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
// 顯示一個系統(tǒng)的paste以及自定義的a,b菜單
if (action == @selector(paste:) ||
action == @selector(aAction) ||
action == @selector(bAction))
{
return YES;
}
else{
return NO;
}
}
運行程序姜凄,顯效果如下
說明:系統(tǒng)的菜單會顯示在自定義菜單之前政溃。
其它說明
如下圖紅色箭頭所指所示,菜單箭頭指針默認向下态秧,可以通過設(shè)置arrowDirection
屬性改變其方向董虱,支持上下左右四個方法。
箭頭指針最下面的點即- (void)setTargetRect:(CGRect)targetRect inView:(UIView *)targetView
方法中targetRect說設(shè)置的位置申鱼,具體指向的點見使用步驟說解釋愤诱。