Как получить выделенный текст из 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, чтобы получить выбор. Смотрите эту ссылку для деталей:

https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITextView_Class/Reference/UITextView.html

UITextField не имеет делегата для изменения диапазона выбора. Мы можем использовать КВО, чтобы наблюдать selectedTextRange собственностью UITextfield,

    [textField addObserver:self forKeyPath:@"selectedTextRange" options:NSKeyValueObservingOptionNew context:NULL];

Или создать UITextField подкласс и переопределение setSelectedTextRange метод.

Другие вопросы по тегам