天天看點

iOS UIMenuController簡介及使用 —— HERO部落格

UIMenuController簡介:

UIMenuController為菜單控制器,是一個單例對象,繼承NSObject,用來剪切、拷貝、粘貼等操作。

UIMenuController使用:

擷取UIMenuController對象:
UIMenuController *menu = [UIMenuController sharedMenuController];
           
設定顯示或者隐藏:
//通過menuVisible屬性設定,預設為NO,也可以通過該屬性擷取菜單欄顯示狀态
menu.menuVisible = YES;

//通過setMenuVisible:(BOOL)menuVisible animated:方法設定,可設定動畫
[menu setMenuVisible:YES animated:YES];
           
設定顯示位置(配合箭頭方向設定):
[menu setTargetRect:CGRectMake(0, cell.frame.size.height * 0.5, cell.frame.size.width, cell.frame.size.height) inView:cell];
           
設定箭頭方向:
/*
UIMenuControllerArrowDefault, // 預設,基于在螢幕上的位置向上或向下
UIMenuControllerArrowUp NS_ENUM_AVAILABLE_IOS(3_2),    // 向上
UIMenuControllerArrowDown NS_ENUM_AVAILABLE_IOS(3_2),  // 向下
UIMenuControllerArrowLeft NS_ENUM_AVAILABLE_IOS(3_2),  // 向左
UIMenuControllerArrowRight NS_ENUM_AVAILABLE_IOS(3_2), // 向右
*/
menu.arrowDirection = UIMenuControllerArrowLeft;           
初始化菜單項UIMenuItem(用于自定義菜單按鈕):
UIMenuItem *printf = [[UIMenuItem alloc] initWithTitle:@"列印" action:@selector(printf:)];
           
設定自定義菜單項(同時有系統菜單項和自定義菜單項,自定義菜單項會排在後面):
//menuItems預設為nil
menu.menuItems = @[printf, audio];           
因為UIMenuController是一個單例對象,如果在一個控制器添加了自定義菜單項,那麼在其他控制器仍會顯示自定義菜單項,若不想顯示,需先清空menuItems屬性:
- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
    
    [UIMenuController sharedMenuController].menuItems = @[];
}           
支援通知:
/*
UIMenuControllerWillShowMenuNotification       // 将要顯示
UIMenuControllerDidShowMenuNotification        // 已經顯示
UIMenuControllerWillHideMenuNotification       // 将要隐藏
UIMenuControllerDidHideMenuNotification        // 已經隐藏
UIMenuControllerMenuFrameDidChangeNotification // frame發生改變
*/           
控件顯示UIMenuController菜單欄需要可以成為firstResponder:
- (BOOL)canBecomeFirstResponder
{
    return YES;
}           
UITextField、UITextView、UIWebView自帶UIMenuController菜單欄,擁有系統方法:
//允許執行的操作
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
    NSLog(@"SEL : %@", NSStringFromSelector(action));

    if (action == @selector(copy:) || action == @selector(printf:) || action == @selector(audioPlay:)) {
        return YES;
    }

    return NO;
}

/*
通過列印可以看到有如下方法,前面加_為私有方法:
cut:
copy:
select:
selectAll:
paste:
delete:
_promptForReplace:
_transliterateChinese:
_insertDrawing:
_showTextStyleOptions:
_lookup:
_define:
_addShortcut:
_accessibilitySpeak:
_accessibilitySpeakLanguageSelection:
_accessibilityPauseSpeaking:
_share:
makeTextWritingDirectionRightToLeft:
makeTextWritingDirectionLeftToRight:
*/           
讓一個非預設支援UIMenuController菜單欄的控件顯示菜單欄:
//自定義的方法,按上述先添加自定義菜單項,再實作相應方法
- (void)printf:(UIMenuController *)menu
{
    NSLog(@"printf: %@", [[_infoArray[_row] model] text]);
}

//系統方法,直接實作相應方法即可
- (void)copy:(UIMenuController *)menu
{
    NSString *str = [[_infoArray[_row] model] text];
    if (!str) return;
    
    [UIPasteboard generalPasteboard].string = str;
}           
讓一個預設支援UIMenuController菜單欄的控件不顯示某項菜單項,可以實作一個子類繼承該控件,重寫canPerformAction: withSender:方法:
//重寫canPerformAction: withSender:方法,禁止select菜單項顯示
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
    if (action == @selector(select:)) {
        return NO;
    }
    
    return [super canPerformAction:action withSender:sender];
}           

Demo下載下傳連結:http://code.cocoachina.com/view/137002。

Demo一級頁面是UITableView,實作了Cell長按顯示菜單欄,可以複制、列印、語音播放Cell文本内容,單擊Cell跳轉二級頁面,可選擇保留或不保留自定義的列印、語音播放菜單項,可粘貼一級頁面複制的文本内容,為UItextView隐藏系統select:方法,效果如下:

iOS UIMenuController簡介及使用 —— HERO部落格

寫部落格的初心是希望大家共同交流成長,部落客水準有限難免有偏頗之處,歡迎批評指正。

繼續閱讀