Отображение и управление меню редактирования

Меню редактирования является контекстным меню, выведенным на экран для предложения команд, которые могут быть выполнены на выборе, таком как слово в текстовом представлении или изображении. Меню редактирования является неотъемлемой частью копии, сокращения и операций вставки, для которых это выводит на экран (потенциально) команды Copy, Сокращение, Вставку, Выбор, и Выбирают All. Однако можно добавить пользовательские элементы меню к меню редактирования для выполнения других видов действий с выборами.

Управление выбором и меню редактирования

Скопировать или сократить что-то в представлении или сделать что-либо еще с ним, что «что-то» должно быть выбрано. Это может быть диапазон текста, изображения, URL, цвета или любого другого представления данных, включая пользовательские объекты. Необходимо управлять выбором объектов в том представлении сами. Если пользователь выбирает объект в представлении путем создания определенного сенсорного жеста (например, двойное касание), необходимо обработать то событие, внутренне записать выбор (и отменить выбор любого предыдущего выбора), и, возможно, визуально укажите новый выбор в представлении. Если для пользователей возможно выбрать многократные объекты в Вашем представлении для операций вставки сокращения копии, необходимо реализовать то поведение множественного выбора.

Когда Ваше приложение решает, что пользователь запросил меню редактирования — который мог быть действием делания выбора — необходимо завершить следующие шаги для отображения меню:

  1. Вызовите sharedMenuController метод класса UIMenuController получить экземпляр контроллера глобального меню.

  2. Вычислите границы выбора, и с получающимся прямоугольником вызывают setTargetRect:inView: метод. Меню редактирования выведено на экран выше или ниже этого прямоугольника, завися, как близко выбор к вершине или нижней части экрана.

  3. Вызовите setMenuVisible:animated: метод (с YES для обоих параметров) для анимации дисплея меню редактирования выше или ниже выбора.

Перечисление 8-1 иллюстрирует, как Вы могли бы вывести на экран меню редактирования в реализации touchesEnded:withEvent: метод для обработки копии, сокращения и операций вставки. (Обратите внимание на то, что пример опускает раздел кода, обрабатывающего выбор.) Этот фрагмент кода также показывает пользовательское представление, отправляющее себя a becomeFirstResponder сообщение, чтобы гарантировать, что это - первый респондент для последующей копии, сокращения и операций вставки.

Перечисление 8-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];
 
    }
}

Меню первоначально включает все команды, для которых первый респондент имеет соответствующий UIResponderStandardEditActions реализации метода (copy:, paste:, и т.д.). Прежде чем меню выведено на экран, однако, система отправляет a canPerformAction:withSender: обменивайтесь сообщениями первому респонденту, который во многих случаях является самим пользовательским представлением. В его реализации этого метода респондент оценивает, применима ли команда (обозначенный селектором в первом параметре) в текущем контексте. Например, если селектор paste: и нет никаких данных в области монтажа типа, который может обработать представление, респондент должен возвратиться NO подавить команду Paste. Если первый респондент не реализует canPerformAction:withSender: метод, или не обрабатывает данную команду, перемещения сообщения цепочка респондента.

Перечисление 8-2 показывает реализацию canPerformAction:withSender: метод, ищущий сообщение, соответствующее cut:, copy:, и paste: селекторы; это включает или отключает Копию, Сокращение и команды меню Paste на основе текущего контекста выбора и, для вставки, содержания области монтажа.

Перечисление 8-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;
}

Обратите внимание на то, что финал else пункт в этом вызовы метода реализация суперкласса, чтобы дать любому суперклассу шанс обработать команды, которые подкласс принимает решение проигнорировать.

Обратите внимание на то, что команда меню, когда реагируется, может изменить контекст для других команд меню. Например, если пользователь выбирает все объекты в представлении, команды Copy и Cut должны быть включены в меню. В этом случае респондент, в то время как меню все еще видимо, может вызвать update на контроллере меню; это приводит к reinvocation canPerformAction:withSender: на первом респонденте.

Добавление пользовательских элементов к меню редактирования

Можно добавить пользовательский элемент к меню редактирования. Когда пользователи касаются этого элемента, команда дается, который влияет на текущую цель специфичным для приложения способом. Платформа UIKit выполняет это через механизм целевого действия. Касание элемента приводит к сообщению действия, отправляемому в первый объект в цепочке респондента, которая может обработать сообщение. Рисунок 8-1 показывает пример пользовательского элемента меню (“Цвет Изменения”).

Рисунок 8-1  меню редактирования с пользовательским элементом меню

Экземпляр UIMenuItem класс представляет пользовательский элемент меню. UIMenuItem объекты имеют два свойства, заголовок и селектор действия, который можно изменить в любое время. Для реализации пользовательского элемента меню необходимо инициализировать a UIMenuItem экземпляр с этими свойствами, добавляет экземпляр к массиву контроллера меню пользовательских элементов меню, и затем реализует метод действия для обработки команды в надлежащем подклассе респондента.

Другие аспекты реализации пользовательского элемента меню характерны для всего кода, использующего одиночный элемент UIMenuController объект. В пользовательском или переопределенном представлении Вы устанавливаете представление, чтобы быть первым респондентом, получить совместно используемый контроллер меню, установить целевой прямоугольник, и затем вывести на экран меню редактирования с вызовом к setMenuVisible:animated:. Простой пример в Перечислении 8-3 добавляет пользовательский элемент меню для изменения цвета пользовательского представления между красным и черным цветом цветом.

Перечисление 8-3  Реализовывая пункт меню Change Color

- (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];
}

Отклонение меню редактирования

Когда Ваша реализация системы или пользовательские возвраты команды, автоматически скрыто меню редактирования. Можно сохранить меню видимым со следующей строкой кода:

[UIMenuController sharedMenuController].menuVisible = YES;

В любое время система может скрыть меню редактирования. Например, когда предупреждение выведено на экран или пользовательские касания в другой области экрана, это скрывает меню. Если у Вас есть состояние или дисплей, зависящий от того, видимо ли меню редактирования, необходимо прислушаться к названному уведомлению UIMenuControllerWillHideMenuNotification и примите соответствующие меры.