Как получить выделенный текст из uitextfield в iphone?
Я работаю над приложением Text to речь в iPhone,
в котором есть текстовое поле, которое принимает ввод, я хочу, чтобы пользователь выбрал некоторую часть текста из текстового поля, и мое приложение преобразует этот выбранный текст в речь.
моя проблема в том, как я могу получить текст, выбранный пользователем из текстового поля?
5 ответов
-[UITextField selectedText]
Хотя UITextField
не имеет selectedText
метод, он соответствует UITextInput
протокол Таким образом, вы можете использовать необходимые свойства и методы UITextInput
протокол для определения selectedText
из UITextField *textField
(или любой объект, который соответствует UITextInput
протокол, такой как UITextView
).
NSString *selectedText = [textField textInRange:textField.selectedTextRange];
NSLog(@"selectedText: %@", selectedText);
Кроме того, вы также можете использовать необходимые свойства и методы UITextInput
рассчитать selectedRange
из UITextField *textField
,
UITextRange *selectedTextRange = textField.selectedTextRange;
NSUInteger location = [textField offsetFromPosition:textField.beginningOfDocument
toPosition:selectedTextRange.start];
NSUInteger length = [textField offsetFromPosition:selectedTextRange.start
toPosition:selectedTextRange.end];
NSRange selectedRange = NSMakeRange(location, length);
NSLog(@"selectedRange: %@", NSStringFromRange(selectedRange));
-[UITextFieldDelegate textFieldDidChangeSelection:]
Хотя, UITextFieldDelegate
не объявляет textFieldDidChangeSelection:
метод делегата как -[UITextViewDelegate textViewDidChangeSelection:]
, вы все еще можете подключиться, когда выбор UITextField
изменился Для этого подкласс UITextField
и используйте метод Swizzling, чтобы добавить свой собственный код в textField.inputDelegate
родная реализация -[UITextInputDelegate selectionDidChange:]
,
// MyTextField.h
#import <UIKit/UIKit.h>
@interface MyTextField : UITextField
@end
// MyTextField.m
#import <objc/runtime.h>
#import "MyTextField.h"
UIKIT_STATIC_INLINE void mySelectionDidChange(id self, SEL _cmd, id<UITextInput> textInput);
@implementation MyTextField {
BOOL swizzled;
}
#pragma mark - UIResponder
// Swizzle here because self.inputDelegate is set after becomeFirstResponder gets called.
- (BOOL)becomeFirstResponder {
if ([super becomeFirstResponder]) {
[self swizzleSelectionDidChange:YES];
return YES;
} else {
return NO;
}
}
// Unswizzle here because self.inputDelegate may become the inputDelegate for another UITextField.
- (BOOL)resignFirstResponder {
if ([super resignFirstResponder]) {
[self swizzleSelectionDidChange:NO];
return YES;
} else {
return NO;
}
}
#pragma mark - Swizzle -[UITextInput selectionDidChange:]
// Swizzle selectionDidChange: to "do whatever you want" when the text field's selection has changed.
// Only call this method on the main (UI) thread because it may not be thread safe.
- (void)swizzleSelectionDidChange:(BOOL)swizzle {
if (swizzle == swizzled || ![self respondsToSelector:@selector(inputDelegate)]) return; // 4.3
Class inputDelegateClass = object_getClass(self.inputDelegate);
SEL mySelector = @selector(mySelectionDidChange:);
class_addMethod(inputDelegateClass, mySelector, (IMP)mySelectionDidChange, "v@:@");
Method myMethod = class_getInstanceMethod(inputDelegateClass, mySelector);
Method uiKitMethod = class_getInstanceMethod(inputDelegateClass, @selector(selectionDidChange:));
method_exchangeImplementations(uiKitMethod, myMethod);
swizzled = swizzle;
// NSLog(@"swizzled? %i", method_getImplementation(uiKitMethod) == (IMP)venmo_selectionDidChange);
}
@end
UIKIT_STATIC_INLINE void mySelectionDidChange(id self, SEL _cmd, id<UITextInput> textInput) {
// Call the native implementation of selectionDidChange:.
[self performSelector:@selector(mySelectionDidChange:) withObject:textInput];
// "Do whatever you want" with the selectedText below.
NSString *selectedText = [textInput textInRange:textInput.selectedTextRange];
NSLog(@"selectedText: %@", selectedText);
}
Я решил свой запрос следующим образом:
Я реализую делегат UITextView и реализую следующий метод
- (void)textViewDidChangeSelection:(UITextView *)textView {
NSRange r = textView.selectedRange;
NSLog(@"Start from : %d",r.location); //starting selection in text selection
NSLog(@"To : %d",r.length); // end position in text selection
NSLog([tv.text substringWithRange:NSMakeRange(r.location, r.length)]); //tv is my text view
}
Это оно!
стриж
В Swift, получение выделенного текста из UITextField
делается так:
if let textRange = myTextField.selectedTextRange {
let selectedText = myTextField.textInRange(textRange)
}
где textRange
это UITextRange
это используется, чтобы получить фактический выбранный текст.
Swift 4
для получения выбранного UITextField:
import UIKit
extension UIView {
func getSelectedTextField() -> UITextField? {
let totalTextFields = getTextFieldsInView(view: self)
for textField in totalTextFields{
if textField.isFirstResponder{
return textField
}
}
return nil
}
func getTextFieldsInView(view: UIView) -> [UITextField] {
var totalTextFields = [UITextField]()
for subview in view.subviews as [UIView] {
if let textField = subview as? UITextField {
totalTextFields += [textField]
} else {
totalTextFields += getTextFieldsInView(view: subview)
}
}
return totalTextFields
}
}
Подобная тема обсуждается здесь: Могу ли я выделить определенный блок текста в UITextField?
AFAIK нет события, если текст выделен. Тем не менее, вы можете настроить NSTimer для просмотра вашего текстового поля и проверки _selectedRange
, Если это изменится, запустите ваш код преобразования текста в речь.
РЕДАКТИРОВАТЬ: я был неправ по поводу выбора. UITextField не может делать то, что вы хотите достичь. Но если вы используете UITextView
вместо этого вы можете реализовать его UITextViewDelegate и переопределить
- (void)textViewDidChangeSelection:(UITextView *)textView
Там вы можете использовать selectedRange
Poperty, чтобы получить выбор. Смотрите эту ссылку для деталей:
UITextField не имеет делегата для изменения диапазона выбора. Мы можем использовать КВО, чтобы наблюдать selectedTextRange
собственностью UITextfield
,
[textField addObserver:self forKeyPath:@"selectedTextRange" options:NSKeyValueObservingOptionNew context:NULL];
Или создать UITextField
подкласс и переопределение setSelectedTextRange
метод.