Swift'de UITextField ve UITextView'un İmleç Konumunu Alma ve Ayarlama


109

Ben deneme oldum UITextFieldve nasıl 's İmleç konumuna çalışmak. Bir dizi Hedef-C yanıtı buldum.

Ancak Swift ile çalıştığım için, mevcut imleç konumunu nasıl elde edeceğimi ve Swift'e nasıl ayarlayacağımı öğrenmek istedim.

Aşağıdaki cevap, deneyimlerimin ve Objective-C'den çevirimin sonucudur.

Yanıtlar:


316

Aşağıdaki içerik hem UITextFieldve için geçerlidir UITextView.

Kullanışlı bilgi

Metin alanı metninin en başı:

let startPosition: UITextPosition = textField.beginningOfDocument

Metin alanı metninin en sonu:

let endPosition: UITextPosition = textField.endOfDocument

Şu anda seçili aralık:

let selectedRange: UITextRange? = textField.selectedTextRange

İmleç konumunu alın

if let selectedRange = textField.selectedTextRange {

    let cursorPosition = textField.offset(from: textField.beginningOfDocument, to: selectedRange.start)

    print("\(cursorPosition)")
}

İmleç konumunu ayarla

Konumu ayarlamak için, bu yöntemlerin tümü aslında aynı başlangıç ​​ve bitiş değerlerine sahip bir aralık ayarlıyor.

Başlangıca

let newPosition = textField.beginningOfDocument
textField.selectedTextRange = textField.textRange(from: newPosition, to: newPosition)

Sonuna kadar

let newPosition = textField.endOfDocument
textField.selectedTextRange = textField.textRange(from: newPosition, to: newPosition)

Mevcut imleç konumunun solundaki bir konuma

// only if there is a currently selected range
if let selectedRange = textField.selectedTextRange {

    // and only if the new position is valid
    if let newPosition = textField.position(from: selectedRange.start, offset: -1) {

        // set the new position
        textField.selectedTextRange = textField.textRange(from: newPosition, to: newPosition)
    }
}

Keyfi bir konuma

Baştan başlayın ve 5 karakter sağa ilerleyin.

let arbitraryValue: Int = 5
if let newPosition = textField.position(from: textField.beginningOfDocument, offset: arbitraryValue) {

    textField.selectedTextRange = textField.textRange(from: newPosition, to: newPosition)
}

İlişkili

Tüm metni seçin

textField.selectedTextRange = textField.textRange(from: textField.beginningOfDocument, to: textField.endOfDocument)

Bir metin aralığı seçin

// Range: 3 to 7
let startPosition = textField.position(from: textField.beginningOfDocument, offset: 3)
let endPosition = textField.position(from: textField.beginningOfDocument, offset: 7)

if startPosition != nil && endPosition != nil {
    textField.selectedTextRange = textField.textRange(from: startPosition!, to: endPosition!)
}

Mevcut imleç konumuna metin ekle

textField.insertText("Hello")

Notlar

  • textField.becomeFirstResponder()Metin alanına odaklanmak ve klavyenin görünmesini sağlamak için kullanın .

  • Metni bir aralıkta nasıl elde edeceğinizi öğrenmek için bu yanıta bakın .

Ayrıca bakınız


StartPosition'un amacı nedir? Onunla ne yapabilirsin? Ayrıca imleç konumunu elde etmek için ihtiyaç duyulabilecek amaç nedir?
Honey

2
@Honey, bu değişken adını burada iki farklı şeyi belirtmek için kullandım. Birincisi, metin alanının başlangıcına atıfta bulunmaktı. İmleci oraya hareket ettirmek istemeniz yararlı olacaktır. İkincisi, seçilen bir metin aralığının yalvarışına atıfta bulunmaktı. Bu aralığı kopyalamak veya üzerine bazı nitelikler ayarlamak istiyorsanız kullanışlıdır.
Suragch

Metin alanı boşken imleci sağa hareket ettirecek bir şey var mı? Cevabını takip ettim ama yapamadım.
Yücel Bayram

1
@yucelbayram, H tuşunu kullanarak imleci sonraya yerleştirebilirsiniz textField.endOfDocument. Eksik harfleri temsil etmek için alt çizgi veya boşluk da kullanabilirsiniz.
Suragch

1
@ArielSD, üzgünüm, bir süredir bunun üzerinde çalışmadım. Hatırlayamıyorum
Suragch

42

benim durumumda DispatchQueue kullanmak zorunda kaldım:

func textViewDidBeginEditing(_ textView: UITextView) {

   DispatchQueue.main.async{
      textField.selectedTextRange = ...
   }
}

bundan başka hiçbir şey ve diğer konular işe yaramadı.

Not: textViewDidBeginEditing'in hangi iş parçacığının çalıştığını iki kez kontrol ettim ve tüm kullanıcı arayüzünün çalışması gerektiği için ana iş parçacığıydı, bu yüzden main.asynch kullanan bu küçük gecikmenin neden işe yaradığından emin değilim.


2
Bu bir gecikme değil, bir sonraki çalışma döngüsü. Büyük olasılıkla metin alanının seçili aralığı, çağrılan işlev tarafından değiştiriliyor textViewDidBeginEditing. Bu yüzden kuyruğa yerleştirdiğinizde, arayan kişi bittikten sonra gerçekleşecektir.
Michael Ozeryansky

@MichaelOzeryansky Evet, ben de öyle düşünüyorum. Ancak bu şu soruyu akla getiriyor: İmleç konumunu manuel olarak ayarlamak için doğru yöntem nedir?
timetowonder

benim durumumda da bu çözümü çalıştı
Hattori Hanzō

1

İmleç konumunu noktanıza ayarlamak için:

textView.beginFloatingCursor(at: CGPoint(x: 10.0, y: 10.0))

İmleç konumunu sıfırlamak için:

textView.endFloatingCursor()

Not : Bu örnek hem Textview hem de Textfield'da çalışır.


@Suragch Floating Cursor, textView veya textField'da imleç konumunu ayarlamanın bir yöntemidir.
Parth Patel

1
let range = field.selectedTextRange

field.text = "hello world"

field.selectedTextRange = range 
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.