不知道有沒有人試過 UIMenuController他里面的五個消息通知
UIMenuControllerWillShowMenuNotification
UIMenuControllerDidShowMenuNotification
UIMenuControllerWillHideMenuNotification
UIMenuControllerDidHideMenuNotification
UIMenuControllerMenuFrameDidChangeNotification
你會發現不管你的menuItems怎么設置,menuVisible不管是YES還是NO,不管menuController是顯示了還是隱藏了,這個消息通過都不會有。就是他們是無效的。反正我搞了半天都不行。
有一個需求,一個UITextView長按文字之后出現UIMenuController文字編輯的選項,這個時候想去通過menu的顯示隱藏來做一些其他的操作。因為menu的菜單一頁可展示的個數是有顯示的,如果要顯示十幾二十個操作的話就要翻頁查找了就不是很友好,所以想通過這個menu的顯示隱藏來控制視圖上自定義的菜單的顯示問題。
既然無法通過Notification來控制了,那還能怎么搞。
第一顯示
出來事件通過判斷這個動作是否可以執行的方法就可以做到。這個方法也是自定義UIMenuController方法必須要重寫的方法
-(BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
}
第二隱藏
我是通過KVO監聽UITextview的鍵值selectedRange
變化來控制的,你取消某段文字的選擇之后selectrange就會發生變化。
[self rac_observeKeyPath:@"selectedRange" options:NSKeyValueObservingOptionNew observer:nil block:^(id value, NSDictionary *change, BOOL causedByDealloc, BOOL affectedOnlyLastComponent) {
}];
代碼:
代碼中引用了ReactiveObjC 處理KVO的可以自己擴展
YHTextView.h
#import <UIKit/UIKit.h>
UIKIT_EXTERN NSNotificationName const kYHTextViewMenuIsShowNotifition;
UIKIT_EXTERN NSNotificationName const kYHTextViewMenuIsHiddenNotifition;
@interface YHTextView : UITextView
- (void)menuInstance;
@end
YHTextView.m
#import "YHTextView.h"
#import <ReactiveObjC/ReactiveObjC.h>
#import <ReactiveObjC/NSObject+RACKVOWrapper.h>
NSNotificationName const kYHTextViewMenuIsShowNotifition = @"kYHTextViewMenuIsShowNotifition";
NSNotificationName const kYHTextViewMenuIsHiddenNotifition = @"kYHTextViewMenuIsHiddenNotifition";
@interface YHTextView()
@property (assign, nonatomic) BOOL menuIsShow;
@end
@implementation YHTextView
#pragma mark - 按鈕事件
- (void)menuInstance
{
[self rac_observeKeyPath:@"selectedRange" options:NSKeyValueObservingOptionNew observer:nil block:^(id value, NSDictionary *change, BOOL causedByDealloc, BOOL affectedOnlyLastComponent) {
[self menuControllerPopShow];
}];
UIMenuController * menu = [UIMenuController sharedMenuController];
[menu setMenuVisible:NO];
UIMenuItem * item1 = [[UIMenuItem alloc] initWithTitle:@" ? " action:@selector(menuMoveLeft)];
UIMenuItem * item2 = [[UIMenuItem alloc] initWithTitle:@" ? " action:@selector(menuMoveRight)];
[menu setMenuItems:@[item1,item2]];
[menu setMenuVisible:YES animated:YES];
// NSMutableArray * itemList = [[NSMutableArray alloc] init];
//
// UIMenuItem *
// item = [[UIMenuItem alloc] initWithTitle:@"加粗" action:@selector(menuCopy)];
// [itemList addObject:item];
//
// item = [[UIMenuItem alloc] initWithTitle:@"斜體" action:@selector(menuCopy)];
// [itemList addObject:item];
//
// item = [[UIMenuItem alloc] initWithTitle:@"清除" action:@selector(menuCopy)];
// [itemList addObject:item];
//
// item = [[UIMenuItem alloc] initWithTitle:@"字顏色" action:@selector(menuCopy)];
// [itemList addObject:item];
//
// item = [[UIMenuItem alloc] initWithTitle:@"描邊" action:@selector(menuCopy)];
// [itemList addObject:item];
//
// item = [[UIMenuItem alloc] initWithTitle:@"字間距" action:@selector(menuCopy)];
// [itemList addObject:item];
//
// item = [[UIMenuItem alloc] initWithTitle:@"下劃線" action:@selector(menuCopy)];
// [itemList addObject:item];
//
// item = [[UIMenuItem alloc] initWithTitle:@"背景色" action:@selector(menuCopy)];
// [itemList addObject:item];
//
// item = [[UIMenuItem alloc] initWithTitle:@"H1" action:@selector(menuCopy)];
// [itemList addObject:item];
//
// item = [[UIMenuItem alloc] initWithTitle:@"H2" action:@selector(menuCopy)];
// [itemList addObject:item];
//
// item = [[UIMenuItem alloc] initWithTitle:@"H3" action:@selector(menuCopy)];
// [itemList addObject:item];
//
// item = [[UIMenuItem alloc] initWithTitle:@"H4" action:@selector(menuCopy)];
// [itemList addObject:item];
}
#pragma mark - menu viewcontrol
-(BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
if(action == @selector(menuMoveLeft) ||
action == @selector(menuMoveRight))
{
[self menuControllerPopShow];
return YES;
}
return NO;
}
- (BOOL)canBecomeFirstResponder {
return YES;
}
- (void)menuMoveLeft
{
dispatch_async(dispatch_get_main_queue(), ^{
if(self.selectedRange.location != 0)
{
NSRange range = self.selectedRange;
range.location = range.location - 1;
range.length = range.length + 1;
self.selectedRange = range;
}
[[UIMenuController sharedMenuController] setMenuVisible:YES animated:NO];
});
}
- (void)menuMoveRight
{
dispatch_async(dispatch_get_main_queue(), ^{
if(NSMaxRange(self.selectedRange) != self.text.length)
{
NSRange range = self.selectedRange;
range.length = range.length + 1;
self.selectedRange = range;
}
[[UIMenuController sharedMenuController] setMenuVisible:YES animated:NO];
});
}
- (void)menuControllerPopShow
{
if(self.selectedRange.length == 0)
{
if(self.menuIsShow)
{
self.menuIsShow = NO;
NSLog(@"隱藏");
[[NSNotificationCenter defaultCenter] postNotificationName:kYHTextViewMenuIsHiddenNotifition object:nil];
}
}
else
{
if(!self.menuIsShow)
{
self.menuIsShow = YES;
NSLog(@"顯示");
[[NSNotificationCenter defaultCenter] postNotificationName:kYHTextViewMenuIsShowNotifition object:nil];
}
}
}
有個問題我們設置textview的selectedRange的時候,在模擬器上非???,效果不是很好,但是在真機上雖然不那么嚴重,但是還是有,不知原因到哪里。??????