編輯菜單是一種上下文菜單窝革,它用來顯示可執(zhí)行的命令,例如文本視圖或圖片中的文字吕座。編輯菜單是復(fù)制虐译、剪切、以及粘貼操作的組成部分吴趴,它顯示(可能的話)復(fù)制漆诽、剪切、粘貼锣枝、選擇厢拭、以及選擇全部命令。
管理選擇和編輯菜單
想要在視圖中復(fù)制或剪切什么撇叁,或用它來做其他事供鸠,其內(nèi)容必須被選擇。它可以是一定范圍的文本陨闹、圖片楞捂、URL、顏色趋厉、或者其他數(shù)據(jù)表示法寨闹,包括自定義對象。你必須自己管理視圖中的選中對象觅廓。如果用戶通過某些操作手勢選擇了視圖中的對象、你必須處理該事件涵但、內(nèi)部記錄所選內(nèi)容(并取消之前的所選內(nèi)容)杈绸、并可能在視圖中直觀的指示新的選擇內(nèi)容帖蔓。如果你想在視圖中實(shí)現(xiàn)對多個(gè)對象的復(fù)制-剪切-粘貼操作,你必須實(shí)現(xiàn)多選擇內(nèi)容(multiple-selection)行為瞳脓。
注意:處理觸摸事件的計(jì)數(shù)塑娇,包括使用手勢識別器,在UIKit Apps的Event Handling Guide中討論劫侧。
當(dāng)app確定用戶要求的編輯菜單(它可以用來處理所選內(nèi)容)的時(shí)候埋酬,你應(yīng)該通過完成以下步驟來顯示菜單:
- 調(diào)用UIMenuController的sharedMenuController類來獲取全局的菜單控制器實(shí)例。
- 計(jì)算選中內(nèi)容的邊界烧栋,并使用結(jié)果矩形來調(diào)用setTargetRect:inView:方法写妥。編輯菜單在上面的矩形的上面或下面顯示,取決于選中內(nèi)容與屏幕的上沿和下沿的靠近程度审姓。
- 調(diào)用setMenuVisible:animated: 方法(兩個(gè)參數(shù)都YES)來動(dòng)態(tài)的在選中內(nèi)容的上方或下方顯示菜單珍特。
圖7-1說明了你應(yīng)該如何在touchesEnded:withEvent:方法的實(shí)現(xiàn)中編輯菜單的顯示,來處理復(fù)制魔吐、剪切扎筒、以及粘貼操作。(注意酬姆,該例子忽略了處理選擇內(nèi)容的代碼嗜桌。)該代碼片段還顯示了自定義視圖給自己發(fā)送becomeFirstResponder消息來確保自己成為第一響應(yīng)者,以便可以進(jìn)行復(fù)制辞色、剪切骨宠、以及粘貼操作。
代碼清單7-1 顯示編輯菜單
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *theTouch = [touches anyObject];
if ([theTouch tapCount] == 2 && [self becomeFirstResponder]) {
// selection management code goes here...
// bring up edit menu.
UIMenuController *theMenu = [UIMenuController sharedMenuController];
CGRect selectionRect = CGRectMake (currentSelection.x, currentSelection.y, SIDE, SIDE);
[theMenu setTargetRect:selectionRect inView:self];
[theMenu setMenuVisible:YES animated:YES];
}
}
菜單初始包含第一響應(yīng)者具有的相應(yīng)UIResponderStandardEditActions方法實(shí)現(xiàn)的所有命令(copy:, paste:等等)淫僻。但是诱篷,在菜單顯示之前系統(tǒng)發(fā)送canPerformAction:withSender:給第一響應(yīng)者,大很多情況下是自定義視圖本身雳灵。在它的方法實(shí)現(xiàn)中棕所,響應(yīng)者評估當(dāng)前上下文中是否應(yīng)用命令。例如悯辙,如果選擇器是paste:琳省,并且在該視圖類型的可以處理的剪貼板中就沒有數(shù)據(jù),響應(yīng)者應(yīng)該返回NO來阻止粘貼對象躲撰。如果響應(yīng)者沒有實(shí)現(xiàn)canPerformAction:withSender:方法针贬,或者沒有處理給定的命令,該消息會(huì)傳遞給響應(yīng)者鏈拢蛋。
代碼清單7-2顯示了canPerformAction:withSender:方法的實(shí)現(xiàn)桦他,它尋找匹配cut:, copy:,和 paste: 選擇器的消息;它基于當(dāng)前選中內(nèi)容啟用或取消復(fù)制谆棱、剪切快压、以及粘貼菜單命令圆仔,對于粘貼,就是是否剪貼板中的內(nèi)容蔫劣。
代碼清單7-2 有條件的啟用菜單命令
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
BOOL retValue = NO;
ColorTile *theTile = [self colorTileForOrigin:currentSelection];
if (action == @selector(paste:) )
retValue = (theTile == nil) &&
[[UIPasteboard generalPasteboard] containsPasteboardTypes:
[NSArray arrayWithObject:ColorTileUTI]];
else if ( action == @selector(cut:) || action == @selector(copy:) )
retValue = (theTile != nil);
else
retValue = [super canPerformAction:action withSender:sender];
return retValue;
}
注意坪郭,方法中的最后一個(gè)else調(diào)用了超類的實(shí)現(xiàn),以便給超類一個(gè)機(jī)會(huì)來處理子類忽略的命令脉幢。
注意歪沃,當(dāng)采取行動(dòng)的時(shí)候,菜單命令可以改變菜單命令的上下文嫌松。例如沪曙,如果用戶選擇視圖中所有的對象,復(fù)制和剪切命令應(yīng)該包含在菜單中豆瘫。在這種情況下珊蟀,響應(yīng)者(在菜單仍可見的時(shí)候)可以調(diào)用菜單控制器的update方法;這導(dǎo)致第一響應(yīng)者的canPerformAction:withSender:重新調(diào)用(reinvocation)外驱。
添加自定義項(xiàng)目到編輯菜單
你可以添加自定義項(xiàng)目到編輯菜單育灸。當(dāng)用戶點(diǎn)擊該項(xiàng)目時(shí),對當(dāng)前應(yīng)用程序的目標(biāo)有影響的命令被發(fā)出昵宇。UIKit框架通過目標(biāo)動(dòng)作機(jī)制來實(shí)現(xiàn)磅崭。一個(gè)項(xiàng)目的點(diǎn)擊導(dǎo)致動(dòng)作消息被發(fā)送給能夠處理該消息的響應(yīng)者鏈中的第一響應(yīng)者。圖7-1展示了自定義菜單項(xiàng)目(改變顏色瓦哎,Change Color)的例子砸喻。
圖 7-1 帶有自定義菜單項(xiàng)目的編輯菜單
UIMenuItem類的實(shí)例代表自定義菜單項(xiàng)目。UIMenuItem對象有兩個(gè)屬性蒋譬,標(biāo)題和動(dòng)作選擇器割岛,你可以在任何時(shí)間改變它們。為了實(shí)現(xiàn)自定義菜單項(xiàng)目犯助,你必須使用這些屬性初始化一個(gè)UIMenuItem實(shí)例癣漆,把這個(gè)實(shí)例添加到菜單控制器的自定義菜單項(xiàng)目數(shù)組中,并且實(shí)現(xiàn)動(dòng)作方法來處理恰當(dāng)?shù)捻憫?yīng)者子類的命令剂买。
實(shí)現(xiàn)自定義菜單項(xiàng)目其他方面惠爽,通常是以全代碼的方式使用UIMenuController單例對象。在自定義或重寫視圖中瞬哼,你設(shè)置該視圖為第一響應(yīng)者婚肆、獲取共享的菜單控制器、設(shè)置目標(biāo)矩形坐慰、然后調(diào)用setMenuVisible:animated:來顯示菜單较性。代碼清單7-3中的簡單例子,添加了一個(gè)自定義菜單項(xiàng)目,用紅黑兩種顏色改變自定義視圖的顏色赞咙。
代碼清單 7-3 實(shí)現(xiàn)改變顏色的菜單項(xiàng)目
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *theTouch = [touches anyObject];
if ([theTouch tapCount] == 2) {
[self becomeFirstResponder];
UIMenuItem *menuItem = [[UIMenuItem alloc] initWithTitle:@"Change Color" action:@selector(changeColor:)];
UIMenuController *menuCont = [UIMenuController sharedMenuController];
[menuCont setTargetRect:self.frame inView:self.superview];
menuCont.arrowDirection = UIMenuControllerArrowLeft;
menuCont.menuItems = [NSArray arrayWithObject:menuItem];
[menuCont setMenuVisible:YES animated:YES];
}
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {}
- (BOOL)canBecomeFirstResponder { return YES; }
- (void)changeColor:(id)sender {
if ([self.viewColor isEqual:[UIColor blackColor]]) {
self.viewColor = [UIColor redColor];
} else {
self.viewColor = [UIColor blackColor];
}
[self setNeedsDisplay];
}
注意:代碼清單7-3中的UIMenuController的arrowDirection屬性永毅,允許你指定尖頭的方向,讓它指向目標(biāo)矩形人弓。
關(guān)閉編輯菜單
當(dāng)你的系統(tǒng)或者地定義命令實(shí)現(xiàn)返回的時(shí)候,編輯菜單自動(dòng)隱藏着逐。你可以使用下面這行代碼讓它繼續(xù)存在:
[UIMenuController sharedMenuController].menuVisible = YES;
系統(tǒng)可以在任何時(shí)候隱藏編輯菜單崔赌。例如,它可以在一個(gè)警告框顯示或者用戶點(diǎn)擊屏幕的任何位置的時(shí)候隱藏耸别。如果你有狀態(tài)健芭、或顯示是基于編輯菜單是否可見,那么你應(yīng)該監(jiān)聽UIMenuControllerWillHideMenuNotification通知秀姐,并采取適當(dāng)?shù)男袆?dòng)慈迈。