I have a UITextView
with some texts. I need to select the text by swiping on textview. I mean when we swipe on the content of textview it should be selected and want to get that string to assign to a NSString
object. is there any method to achieve this. Please suggest me some solutions to do that.
Asked
Active
Viewed 639 times
3

Shaheer Palollathil
- 303
- 3
- 15
-
You want to select the whole textView or let it depends on the swipe offset? – Thanh-Nhon Nguyen Jun 25 '14 at 08:39
-
@NhonNguyen i don't want to select whole text view, i want to select only swipe offset. – Shaheer Palollathil Jun 25 '14 at 08:41
-
I think this is possible but it does require efforts and tricks. Personally, seems that it's not a good idea as it causes bad UX (User experience). Users don't know which part of the text that they are selecting. Why don't you just enable text selection? – Thanh-Nhon Nguyen Jun 25 '14 at 08:46
-
1Sounds like he's trying to build some intuitive text editor on iOS device using swipe to select text rather than the long and tedious (slightly more accurate) long press, drag and select. Might need to subclass your UITextView and handle the touchesBegan, touchesMove methods, as well as the finger position relative to the UITextView to do what you want. You might run into a conflicting situation with regards to swipe select vs scrolling the UITextView. – Zhang Jun 25 '14 at 09:06
2 Answers
1
You can add pan gesture to UITextView to get CGPoint(finger positon), then use UITextInput protocol method to translate CGPoint to UITextPosition, then translate to UITextRange. Use UITextRange to select text programatically.
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.textView.editable=NO;
UIPanGestureRecognizer *pan=[[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(translatePan:)];
[self.textView addGestureRecognizer:pan];
UIMenuItem *menuItem = [[UIMenuItem alloc]initWithTitle:@"翻译" action:@selector(translate)];
[[UIMenuController sharedMenuController] setMenuItems:[NSArray arrayWithObject:menuItem]];
}
- (void)translatePan:(UIPanGestureRecognizer *)ges
{
CGPoint point = [ges locationInView:ges.view];
if (ges.state == UIGestureRecognizerStateBegan)
{
startPoint = point;
}
else if (ges.state == UIGestureRecognizerStateChanged || ges.state == UIGestureRecognizerStateEnded)
{
UITextPosition *start = [self.textView closestPositionToPoint:startPoint];
UITextPosition *end = [self.textView closestPositionToPoint:point];
UITextRange *range = [self.textView textRangeFromPosition:start toPosition:end];
[self.textView select:self.textView];
self.textView.selectedTextRange = range;
}
if (ges.state == UIGestureRecognizerStateEnded)
{
UIMenuController *mvc=[UIMenuController sharedMenuController];
[mvc setTargetRect:CGRectMake(startPoint.x, startPoint.y, point.x-startPoint.x, 20) inView:self.textView];
[mvc update];
[mvc setMenuVisible:YES animated:YES];
}
}
- (void)translate
{
NSLog(@"selected text:%@",[self.textView.text substringWithRange:self.textView.selectedRange]);
}

Han Pengbo
- 1,338
- 1
- 18
- 37
0
You can use the NSLayoutManager for the text view for this.
// Get the location in the view
CGPoint location = [swipeRecogniser locationInView:textView];
// Get the index in the string
NSUInteger charIndex = [textView.layoutManager characterIndexForPoint:location inTextContainer:textView.textContainer fractionOfDistanceBetweenInsertionPoints:NULL];
This will get you the character index in your string from a CGPoint location. You'll probably want to get the location at the start and end of your swipe (possibly change the end location based on the velocity of the swipe?). You can then use the start and end indexes to get a substring from the main string, and boom! Problem solved!
Hope this helps, let me know if anything is unclear :)

George Green
- 4,807
- 5
- 31
- 45