簡體   English   中英

如何從iphone中的uitextfield中選擇文本?

[英]how to get selected text from uitextfield in iphone?

我正在研究iPhone中的文本到語音應用程序,

其中有一個文本字段接受輸入,我希望用戶從文本字段中選擇一部分文本,我的應用程序將所選文本轉換為語音。

我的問題是我如何獲得用戶從文本字段中選擇的文本?

-[UITextField selectedText]

雖然UITextField沒有selectedText方法,但它符合UITextInput協議 所以,可以使用所要求的性質&所述的方法UITextInput協議來確定selectedText一個的UITextField *textField (或符合任何對象UITextInput協議,諸如UITextView )。

NSString *selectedText = [textField textInRange:textField.selectedTextRange];
NSLog(@"selectedText: %@", selectedText);

另外,您還可以使用UITextInput所需的屬性和方法來計算UITextField *textFieldselectedRange

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 ,用於獲取實際選定的文本。

這里討論類似的主題: 我可以在UITextField中選擇特定的文本塊嗎?

如果選擇了文本,則AFAIK沒有事件。 但是,您可以設置NSTimer來觀察文本字段並檢查_selectedRange 如果它發生變化,請啟動您的文字轉語音代碼。

編輯 :我選擇錯了。 UITextField無法實現您想要實現的目標。 但是,如果您使用UITextView ,則可以實現其UITextViewDelegate並覆蓋

- (void)textViewDidChangeSelection:(UITextView *)textView

在那里,您可以使用selectedRange屬性來獲取選擇。 有關詳情,請參閱此參考

https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITextView_Class/Reference/UITextView.html#//apple_ref/doc/uid/TP40006898-CH3-SW13

UITextField沒有委托來獲取選擇范圍更改。 我們可以使用KVO來觀察UITextfield selectedTextRange屬性。

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

或者創建UITextField子類並覆蓋setSelectedTextRange方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM