问题
I'm creating an iOS 8 app with Xcode 6.0.1 for my iPhone 5 (which has iOS 8.0.2 on it). I want to make it so that when a user clicks on my UITextView
, all the text gets selected so he can easily start typing and erase what was there (but I don't want the text to be automatically erased because the user may want to keep it or append to it). To do this, I have the following code:
- (void)textViewDidBeginEditing:(UITextView *)textView {
if ([textView hasText]) {
NSLog(@"selectedRange before: %d", textView.selectedRange.length);
[textView selectAll:self];
NSLog(@"selectedRange after: %d", textView.selectedRange.length);
}
}
When this method gets called, the console output is what I expect (i.e. the selectedRange
length is the same as the number of characters in the textView
's text). However, nothing shows up as selected in the UITextView
and it doesn't act selected (i.e. no selection menu pops up).
I have seen multiple questions like this on the internet, but none of the provided solutions worked for me (and some of them wrote it off as a bug without providing any solution). Changing the sender id to something other than self
(such as nil
) did not help, and neither did it help to call [textView select:self]
as one person suggested. I have also tried this code:
- (void)textViewDidBeginEditing:(UITextView *)textView {
if ([textView hasText]) {
UITextRange *range = [textView textRangeFromPosition:textView.beginningOfDocument toPosition:textView.endOfDocument];
[textView setSelectedTextRange:range];
}
}
But, it has the same problem.
Any suggestions?
回答1:
This solution works too and does not require subclassing UITextView
, just put this function on your delegate:
OBJECTIVE C -
- (BOOL)textViewShouldBeginEditing:(UITextView *)textView {
dispatch_async(dispatch_get_main_queue(), ^{
[textView selectAll:nil];
});
return YES;
}
SWIFT 3 -
func textViewDidBeginEditing(_ textView: UITextView) {
DispatchQueue.main.async {
textView.selectAll(nil)
}
}
回答2:
@brentvatne 's solution worked for me. Posting the Swift syntax so people can copy and paste in the future.
func textViewShouldBeginEditing(textView: UITextView) -> Bool {
dispatch_async(dispatch_get_main_queue()) {
textView.selectAll(nil)
}
return true
}
回答3:
The best solution I've found for this issue so far is to create a custom UITextView
(i.e. create a new class that extends UITextView
) and then implement the selectAll
method like this:
- (void)selectAll:(id)sender {
[super selectAll:sender];
UITextRange *selectionRange = [self textRangeFromPosition:self.beginningOfDocument toPosition:self.endOfDocument];
[self performSelector:@selector(setSelectedTextRange:) withObject:selectionRange afterDelay:0.0];
}
Then when you use a text view, set its type to your custom text view type (in your code and in the storyboard). Now you can successfully call the selectAll
method whenever you need to. I suppose this should work with UITextField
too, but I haven't tried it yet.
来源:https://stackoverflow.com/questions/26307436/uitextview-selectall-method-not-working-as-expected