模仿UITextView的默认双击行为

时间:2014-12-28 01:43:46

标签: ios xcode uitextview uigesturerecognizer uitapgesturerecognizer

当用户在UITextView中使用两根手指点击时,是否有人知道调用哪些方法?

当用户用两根手指点击时,会选择段落中的整个文本。我想以编程方式实现相同的选择,以便在我的自定义单击手势方法中选择此段落。

2 个答案:

答案 0 :(得分:2)

根据UITextView双击手势识别器的默认行为判断,我认为selectAll:是调用来处理文本选择的方法。您可以使用现有selectAll:方法中的tapTextViewGesture:(如评论中所述),在识别单击手势识别器时强制您的文字视图选择文字。

如果您希望文本选项自动显示以响应默认的双击手势识别器(即剪切,复制,粘贴等),请将selectAll:设置为self:< / p>

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

否则,只需选择文字而不显示菜单,请将其设置为nil

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

<强>更新

正如OP在评论中指出的那样,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;
}

答案 1 :(得分:1)

请参阅UITextInputTokenizer协议参考:

  

采用UITextInputTokenizer协议的类的实例是一个标记化器;标记化器允许文本输入系统评估不同粒度的文本单元。始终参考存储或参考方向评估文本单位的粒度。

根据协议,使用- (UITextRange *)rangeEnclosingPosition:(UITextPosition *)position withGranularity:(UITextGranularity)granularity inDirection:(UITextDirection)direction并将UITextGranularity设置为UITextGranularityParagraph,以使用您设置的粒度检测textRange。

- (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>