How to calculate NSRange of NSString at certain position in UITextView
When I tap on a certain positio开发者_如何学Pythonn in a UITextView, I want to retrieve the substring of the NSString which is shown at the line.
I have e.g. 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:
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; }
Get NSRange in textViewDidChangeSelection event:
//touch textView will trigger the event, too -(void)textViewDidChangeSelection:(UITextView *)textView { NSLog(@"textViewDidChangeSelection"); NSRange range=[sermonTextView selectedRange]; }
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; }
精彩评论