2012-06-22 31 views
24

ai có thể giúp tôi với điều này: tôi cần phải thực hiện UITextField cho số đầu vào. Số này phải luôn ở định dạng thập phân với 4 địa điểm, ví dụ: 12.3456 hoặc 12.3400. Vì vậy, tôi đã tạo NSNumberFormatter giúp tôi có vị trí thập phân.làm thế nào để di chuyển con trỏ trong UITextField sau khi thiết lập giá trị của nó

Tôi đang thiết lập các giá trị UITextField trong phương pháp

-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string . Tôi nhập vào đầu vào, sử dụng trình định dạng và cuối cùng gọi [textField setText: myFormattedValue];

Điều này làm việc tốt nhưng cuộc gọi này cũng di chuyển con trỏ đến cuối trường của tôi. Điều đó là không mong muốn. Ví dụ. Tôi có 12.3400 trong trường của tôi và con trỏ nằm ở đầu và số loại người dùng 1. Giá trị kết quả là 112.3400 nhưng con trỏ được di chuyển ở cuối. Tôi muốn kết thúc bằng con trỏ khi người dùng mong đợi (ngay sau số 1 được thêm gần đây). Có một số chủ đề về cách đặt con trỏ trong TextView nhưng đây là UITextField. Tôi cũng đã cố gắng để nắm bắt selectedTextRange của trường, lưu vị trí con trỏ đúng cách nhưng sau khi gọi setText phương thức, điều này sẽ tự động thay đổi và nguồn gốc UITextRange bị mất (thay đổi thành hiện tại). hy vọng lời giải thích của tôi là rõ ràng.

Vui lòng giúp tôi với điều này. Cảm ơn nhiều.

EDIT: Cuối cùng, tôi quyết định chuyển đổi chức năng để thay đổi định dạng sau khi chỉnh sửa toàn bộ và hoạt động đủ tốt. Tôi đã thực hiện việc này bằng cách thêm công cụ chọn forControlEvents:UIControlEventEditingDidEnd.

+0

Khi bạn đọc những 'selectedTextRange', bạn không thể sao chép nó như một thuộc tính trong lớp hoạt động như các' UITextFieldDelegate' và sau đó tái thiết lập nó sau 'setText:'? –

+1

Phillip, không hoạt động.Sau khi bạn đặt văn bản với setText, UITextRange bạn đã thu thập trước khi thiết lập văn bản được đặt lại thành null và vì vậy bạn không thể áp dụng lại nó sau đó đến UITextField đã hoàn thành. – JasonD

Trả lời

2

Triển khai mã được mô tả trong câu trả lời này: 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: Từ this answer, có vẻ như bạn chỉ có thể sử dụng mã này với UITextField của bạn nếu bạn đang sử dụng iOS 5 hoặc cao hơn. Nếu không, bạn cần sử dụng một UITextView thay thế.

38

Sau khi thuộc tính UITextField.text được thay đổi, mọi tham chiếu trước đó thành UITextPosition hoặc UITextRange đối tượng được liên kết với văn bản cũ sẽ được đặt thành 0 sau khi bạn đặt thuộc tính văn bản. Bạn cần phải lưu trữ những gì các văn bản bù đắp sẽ được sau khi thao tác sẽ được TRƯỚC KHI bạn thiết lập các tài sản văn bản.

này làm việc cho tôi (lưu ý, bạn phải kiểm tra xem cursorOffset là < textField.text.length nếu bạn loại bỏ bất kỳ ký tự từ t trong ví dụ dưới đây):

- (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

Làm việc tuyệt vời cho tôi. Cảm ơn, JasonD! –

+2

Hoạt động hoàn hảo. Cảm ơn bạn!!! – RohinNZ

+0

tnx rất nhiều, tôi đã thêm phiên bản nhanh hơn bên dưới cho những người lười biếng :) – ergunkocak

3

Và đây là nhanh chóng phiên bản:

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

đây là một nhanh chóng 3 phiên bản

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

Điều gì thực sự w orked đối với tôi là rất đơn giản, chỉ cần sử dụng công văn async chính:

DispatchQueue.main.async(execute: { 
    textField.selectedTextRange = textField.textRange(from: start, to: end) 
}) 
Các vấn đề liên quan