Имитировать поведение двойного касания по умолчанию UITextView


Кто-нибудь знает, какие методы вызываются, когда пользователь нажимает двумя пальцами на UITextView?

Когда пользователь нажимает двумя пальцами, выбирается весь текст в абзаце. Я хотел бы реализовать тот же выбор программно, чтобы сделать этот выбор абзаца доступным в моем пользовательском методе жестов с одним касанием.

2 2

2 ответа:

Судя по поведению распознавателя жестов двойного касания по умолчанию UITextView, я думаю, что selectAll: - это метод, вызываемый для обработки выделения текста. Аналогичным образом вы можете принудительно выбрать текст в представлении текста при распознавании вашего распознавателя жестов с одним касанием, используя selectAll: в существующем методе tapTextViewGesture: (как описано в вашем комментарии).

Если вы хотите, чтобы параметры текста отображались автоматически, как они это делают в ответ на распознаватель жестов двойного касания по умолчанию (т. е. вырезать, копировать, паста и др.), установить selectAll: в self:

- (IBAction)tapTextViewGesture:(id)sender {
    [self.textView selectAll:self]; 
}

В противном случае, чтобы просто выделить текст без отображения меню, установите его в nil:

- (IBAction)tapTextViewGesture:(id)sender {
    [self.textView selectAll:nil]; 
}

Обновлено

Как указал ОП в комментариях, распознаватель жестов двойного касания UITextView первоначально приводит только к выбору одного абзаца.

Сначала выведите меню Правка из текущего положения курсора:

// Access the application's shared menu
UIMenuController *menu = [UIMenuController sharedMenuController];

// Calculate the cursor's position within the superview
// and convert it to a CGRect
CGPoint cursorPosition = [self.textView caretRectForPosition:self.textView.selectedTextRange.start].origin;
CGPoint cursorPositionInView = [self.textView convertPoint:cursorPosition toView:self.view];
CGRect menuRect = CGRectMake(cursorPositionInView.x, cursorPositionInView.y, 0, 0);

// Show the menu from the cursor's position
[menu setTargetRect:menuRect inView:self.view];
[menu setMenuVisible:YES animated:YES];

Затем, чтобы выбрать текущий абзац, вот что я скажу: рекомендую:

// Break the text into components separated by the newline character
NSArray *paragraphs = [self.textView.text componentsSeparatedByString:@"\n"];

// Keep a tally of the paragraph character count
int characterCount = 0;

// Go through each paragraph
for (NSString *paragraph in paragraphs) {

    // If the total number of characters up to the end
    // of the current paragraph is greater than or
    // equal to the start of the textView's selected
    // range, select the most recent paragraph and break
    // from the loop
    if (characterCount + paragraph.length >= self.textView.selectedRange.location) {
        [self.textView setSelectedRange:NSMakeRange(characterCount, paragraph.length)];
        break;
    }

    // Increment the character count by adding the current
    // paragraph length + 1 to account for the newline character
    characterCount += paragraph.length + 1;
}

См.UITextInputTokenizer ссылка на протокол:

экземпляр класса, который использует протокол UITextInputTokenizer, является токенизатором; токенизатор позволяет системе ввода текста оценивать текстовые единицы различной степени детализации. Степень детализации текстовых единиц всегда оценивается с учетом направления хранения или ссылки.

По протоколу используйте - (UITextRange *)rangeEnclosingPosition:(UITextPosition *)position withGranularity:(UITextGranularity)granularity inDirection:(UITextDirection)direction и установите UITextGranularity в UITextGranularityParagraph для обнаружения текстового диапазона с детализацией ты все устроил.

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{

  if (touches.count == 2) {
    UITouch *touch = [[event allTouches] anyObject];
    CGPoint touchLocation = [touch locationInView:self.textView];

    //calculate the distance from touch
    UITextPosition *position = [self.textView closestPositionToPoint:touchLocation];
    NSUInteger distanceFromTouch = [self.textView offsetFromPosition:self.textView.beginningOfDocument
                                                          toPosition:position];
    //calculate the position by offset 
    UITextPosition *positionOffset = [self.textView positionFromPosition:self.textView.beginningOfDocument
                                                  offset:distanceFromTouch];

    //set up the granularity
    UITextGranularity granularity = UITextGranularityParagraph;

    //implement the protocol
    id<UITextInputTokenizer> tokenizer = self.textView.tokenizer;
    UITextRange *textRange = [tokenizer rangeEnclosingPosition:positionOffset
                                               withGranularity:granularity
                                                   inDirection:UITextWritingDirectionLeftToRight];

    //select the textRange
    [self.textView setSelectedTextRange:textRange];

    self.textView.keyboardType = UIKeyboardTypeNamePhonePad;

  }
}

Не забудьте назначить протокол. @interface ViewController ()<UITextInputTokenizer>