简体   繁体   中英

How to calculate NSRange of NSString at certain position in UITextView

When I tap on a certain position in a UITextView, I want to retrieve the substring of the NSString which is shown at the line.

I have eg a UITextView which displays a string, using 16 lines. When I tap on position (200, 150), I want the substring which is shown by UITextView on that tap.

Any suggestions on how to achieve this?

If I understand your question correctly this is a possible solution. In your viewcontroller add an IBOutlet to a UITextView and make sure your viewcontroller implements the UITextViewDelegate. When connecting the UITextView to the FileOwner in InterfaceBuilder make sure you also point the delegate of the UITextView to the FileOwner.

@interface StackOverFlowViewController : UIViewController<UITextViewDelegate> {

    IBOutlet UITextView *textView;
}
@end

Then in your UIViewController implementation file add this UITextViewDelegate Method.

- (void)textViewDidChangeSelection:(UITextView *)aTextView {

  NSRange rangeOfSelection = textView.selectedRange;
  NSString *selectedText = [textView.text substringWithRange:rangeOfSelection];
  UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Selection Changed" message:selectedText delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
  [alert show];
  [alert release];
}

Then each time you make a selection in the UITextView this method will get called. Use the selectedRange property of UITextView to get the NSRange the User made. From there you can just get the text from the UITextView and generate the correct substring.

I just added a UIAlertView in the textViewDidChangeSelection method to display the substring

You must set UITextView both selectable and editable. However the keyboard will show up when you select, which will let user feel strange. I tried to hide keyboard(by resignFirstResponder) in the KeyboardDidShow event, but the NSRange will not be correct especially when you scroll UITextView and select. If you set UITextView selectable but not editable, then you must have a long press to get the TextViewDidChangeSelection event but keyboard will not show up, then NSRange will be correct.

Later I found a perfect way to solve the problem by moving the keyboard to a far location so you don't need long press and can get accurate NSRange by just a touch. Here is the codes:

  1. find how to control the keyboard:

    //define in common area UIView *systemKeyboard;

    //touch textView will trigger the event, if textView is editable and selectable. No more use KeyboardDidShow event

    -(BOOL)textViewShouldBeginEditing:(UITextView )textView{ NSLog(@"textViewShouldBeginEditing"); if(!systemKeyboard){ UIWindow window1 = [UIApplication sharedApplication].windows[1]; for (int i = 0; i < window1.subviews.count; i++) { UIView *keyBoard1 = window1.subviews[i]; if ([keyBoard1 isKindOfClass:NSClassFromString(@"UIInputSetContainerView")]) { systemKeyboard = keyBoard1;//now we can control keyboard location break; } } } CGRect rec1=systemKeyboard.frame; systemKeyboard.frame=CGRectMake(2000, 2000, rec1.size.width, rec1.size.height); return YES; }

  2. Get NSRange in textViewDidChangeSelection event:

    //touch textView will trigger the event, too -(void)textViewDidChangeSelection:(UITextView *)textView { NSLog(@"textViewDidChangeSelection"); NSRange range=[sermonTextView selectedRange]; }

  3. Move back keyboard in other ShouldBeginEditing occasions:

    //You must close keyboard somewheres, for example if you have also a search bar that will use the keyboard, and you should show the keyboard now. -(BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar{ NSLog(@"searchBarShouldBeginEditing"); if(systemKeyboard){ CGRect rec1=systemKeyboard.frame; systemKeyboard.frame=CGRectMake(0, 0, rec1.size.width, rec1.size.height); // no need [sermonTextView resignFirstResponder]; // no need [searchBar1 becomeFirstResponder]; } ......... return YES; }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM