2012-06-22 29 views
24

może mi ktoś w tym pomóc: muszę wprowadzić UITextField dla numeru wejścia. Ta liczba powinna zawsze być w formacie dziesiętnym z 4 miejscami, np. 12.3456 lub 12.3400. Stworzyłem więc NSNumberFormatter, który pomaga mi w miejscach dziesiętnych.jak przenieść kursor w UITextField po ustawieniu jego wartości

ja ustawienie wartości UITextField w

-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string metody. Przetwarzam dane wejściowe, używam formatera i na koniec wywołuję [textField setText: myFormattedValue];

Działa to dobrze, ale to wywołanie powoduje również przesunięcie kursora na koniec mojego pola. To niechciane. Na przykład. Mam 12.3400 w moim polu, a kursor znajduje się na samym początku, a typy użytkowników 1. Wartość wyniku to 112.3400, ale kursor jest przesuwany na końcu. Chcę zakończyć kursorem, gdy użytkownik tego oczekuje (zaraz po dodaniu ostatnio dodanego numeru 1). Istnieją pewne tematy dotyczące ustawiania kursora w TextView, ale jest to UITextField. Próbowałem również złapać selectedTextRange pola, które zapisuje pozycję kursora poprawnie, ale po wywołaniu metody setText, to automatycznie zmienia się i pochodzenie UITextRange zostaje utracone (zmienione na bieżące). mam nadzieję, że moje wyjaśnienie jest jasne.

Proszę, pomóż mi z tym. Dziękuję Ci bardzo.

EDIT: W końcu zdecydowałem się przełączyć funkcjonalność na zmianę formatu po całej edycji i działa wystarczająco dobrze. Zrobiłem to przez dodanie selektora forControlEvents:UIControlEventEditingDidEnd.

+0

Kiedy czytasz 'selectedTextRange', nie możesz skopiować go jako właściwość w klasie, który działa jako' UITextFieldDelegate' a następnie ponownie zestaw to po 'setText:'? –

+1

Phillip, to nie działa.Po ustawieniu tekstu za pomocą setText, zmienna UITextRange, którą zebrałeś przed ustawieniem tekstu, zostanie zresetowana do wartości null, a więc nie będzie można ponownie zastosować go do ukończonego UITextField. – JasonD

Odpowiedz

2

Wdrożenie kod opisany w tej odpowiedzi: Moving the cursor to the beginning of UITextField

NSRange beginningRange = NSMakeRange(0, 0); 
NSRange currentRange = [textField selectedRange]; 
if(!NSEqualRanges(beginningRange, currentRange)) 
{ 
    [textField setSelectedRange:beginningRange]; 
} 

EDIT: Od this answer, wygląda na to można po prostu użyć tego kodu z UITextField jeśli używasz iOS 5 lub nowszym. W przeciwnym razie musisz użyć UITextView zamiast tego.

38

Po własnością UITextField.text ulega zmianie, wszelkie wcześniejsze odniesienia do UITextPosition lub UITextRange obiektów, które były związane ze starym tekstem zostanie ustawiony na zero po ustawieniu właściwości tekstu. Musisz zapamiętać, jakie będzie przesunięcie tekstu po manipulacji, zanim ustawisz właściwość text.

Ten pracował dla mnie (uwaga, trzeba jednak sprawdzić, czy cursorOffset jest < textField.text.length jeśli usunąć wszystkie znaki z t w poniższym przykładzie):

- (BOOL) textField:(UITextField *) textField shouldChangeCharactersInRange:(NSRange) range replacementString:(NSString *) string 

{ 
    UITextPosition *beginning = textField.beginningOfDocument; 
    UITextPosition *start = [textField positionFromPosition:beginning offset:range.location]; 
    UITextPosition *end = [textField positionFromPosition:start offset:range.length]; 
    UITextRange *textRange = [textField textRangeFromPosition:start toPosition:end]; 

    // this will be the new cursor location after insert/paste/typing 
    NSInteger cursorOffset = [textField offsetFromPosition:beginning toPosition:start] + string.length; 

    // now apply the text changes that were typed or pasted in to the text field 
    [textField replaceRange:textRange withText:string]; 

    // now go modify the text in interesting ways doing our post processing of what was typed... 
    NSMutableString *t = [textField.text mutableCopy]; 
    t = [t upperCaseString]; 
    // ... etc 

    // now update the text field and reposition the cursor afterwards 
    textField.text = t; 
    UITextPosition *newCursorPosition = [textField positionFromPosition:textField.beginningOfDocument offset:cursorOffset]; 
    UITextRange *newSelectedRange = [textField textRangeFromPosition:newCursorPosition toPosition:newCursorPosition]; 
    [textField setSelectedTextRange:newSelectedRange]; 

    return NO; 
} 
+2

Sprawdziło się doskonale dla mnie. Dziękuję, JasonD! –

+2

Działa idealnie. Dziękuję Ci!!! – RohinNZ

+0

tnx bardzo dużo, dodałem wersję swift poniżej dla leniwych :) – ergunkocak

3

A oto szybki wersja:

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { 
    let beginning = textField.beginningOfDocument 
    let start = textField.positionFromPosition(beginning, offset:range.location) 
    let end = textField.positionFromPosition(start!, offset:range.length) 
    let textRange = textField.textRangeFromPosition(start!, toPosition:end!) 
    let cursorOffset = textField.offsetFromPosition(beginning, toPosition:start!) + string.characters.count 

// just used same text, use whatever you want :) 
    textField.text = (textField.text! as NSString).stringByReplacingCharactersInRange(range, withString: string) 

    let newCursorPosition = textField.positionFromPosition(textField.beginningOfDocument, offset:cursorOffset) 
    let newSelectedRange = textField.textRangeFromPosition(newCursorPosition!, toPosition:newCursorPosition!) 
    textField.selectedTextRange = newSelectedRange 

    return false 
} 
2

Oto szybki 3 wersja

extension UITextField { 
    func setCursor(position: Int) { 
     let position = self.position(from: beginningOfDocument, offset: position)! 
     selectedTextRange = textRange(from: position, to: position) 
    } 
} 
0

Co w rzeczywistości orked dla mnie było bardzo proste, wystarczy stosować wysyłka główny asynchroniczny:

DispatchQueue.main.async(execute: { 
    textField.selectedTextRange = textField.textRange(from: start, to: end) 
}) 
Powiązane problemy