Swift에서 UITextField 및 UITextView의 커서 위치 가져 오기 및 설정


109

나는 실험을 해왔고 UITextField커서 위치로 작업하는 방법. 나는 다음과 같이 많은 관계 Objective-C 답변을 찾았습니다.

하지만 Swift로 작업하고 있기 때문에 현재 커서 위치를 가져오고 Swift에서 설정하는 방법을 배우고 싶었습니다.

아래 답변은 Objective-C에서 실험 및 번역 한 결과입니다.

답변:


316

다음 내용은 UITextFieldUITextView.

유용한 정보

텍스트 필드 텍스트의 맨 처음 :

let startPosition: UITextPosition = textField.beginningOfDocument

텍스트 필드 텍스트의 맨 끝 :

let endPosition: UITextPosition = textField.endOfDocument

현재 선택된 범위 :

let selectedRange: UITextRange? = textField.selectedTextRange

커서 위치 가져 오기

if let selectedRange = textField.selectedTextRange {

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

    print("\(cursorPosition)")
}

커서 위치 설정

위치를 설정하기 위해 이러한 모든 방법은 실제로 시작 및 종료 값이 동일한 범위를 설정합니다.

처음으로

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

끝까지

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

현재 커서 위치의 왼쪽 한 위치로

// 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)
    }
}

임의의 위치로

처음부터 시작하여 오른쪽으로 5 자 이동합니다.

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

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

관련

모든 텍스트 선택

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

텍스트 범위 선택

// 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!)
}

현재 커서 위치에 텍스트 삽입

textField.insertText("Hello")

노트

  • 사용하여 textField.becomeFirstResponder()텍스트 필드에 포커스를 키보드가 나타나도록.

  • 특정 범위에서 텍스트를 얻는 방법 은 이 답변 을 참조하십시오 .

또한보십시오


startPosition의 목적은 무엇입니까? 그것으로 무엇을 할 수 있습니까? 또한 커서 위치를 가져 오는 데 필요한 목적은 무엇입니까?

2
@ 여보, 나는 그 변수 이름을 여기에서 두 가지 다른 것을 참조하기 위해 사용했습니다. 첫 번째는 텍스트 필드의 시작 부분을 참조하는 것입니다. 커서를 거기로 옮기고 싶을 때 유용합니다. 두 번째는 선택한 범위의 텍스트를 구걸하는 것입니다. 해당 범위를 복사하거나 일부 속성을 설정하려는 경우 유용합니다.
Suragch

텍스트 필드가 비어있는 동안 커서를 오른쪽으로 이동할 것이 있습니까? 나는 당신의 대답을 따랐지만 나는 그것을 만들 수 없었다.
Yucel Bayram

1
@yucelbayram,을 사용하여 H 뒤에 커서를 놓을 수 있습니다 textField.endOfDocument. 누락 된 문자를 나타 내기 위해 밑줄이나 공백을 사용할 수도 있습니다.
Suragch

1
@ArielSD, 죄송합니다. 한동안이 작업을하지 않았습니다. 기억이 안나요.
Suragch 19

42

제 경우에는 DispatchQueue를 사용해야했습니다.

func textViewDidBeginEditing(_ textView: UITextView) {

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

이것과 다른 스레드에서 다른 것은 작동하지 않았습니다.

추신 : 어떤 스레드가 textViewDidBeginEditing이 실행되고 있는지 두 번 확인했으며 모든 UI가 실행되어야하므로 주 스레드 였으므로 main.asynch를 사용하여 약간의 지연이 작동하는 이유를 모르겠습니다.


2
지연이 아니라 다음 실행 루프입니다. 대부분의 경우 텍스트 필드의 선택한 범위가를 호출 한 동일한 함수에 의해 수정되고 textViewDidBeginEditing있습니다. 따라서 대기열에 배치하면 발신자가 완료된 후에 발생합니다.
Michael Ozeryansky

@MichaelOzeryansky 그래, 나도 그렇게 생각한다. 그러나 이것은 질문을합니다. 커서 위치를 수동으로 설정하는 올바른 방법은 무엇입니까?
timetowonder

제 경우
에도이

1

포인트에서 커서 위치 설정 :

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

커서 위치 재설정 :

textView.endFloatingCursor()

참고 :이 예제는 Textview 및 Textfield 모두에서 작동합니다.


@Suragch Floating Cursor는 textView 또는 textField에서 커서 위치를 설정하는 한 가지 방법입니다.
Parth Patel

1
let range = field.selectedTextRange

field.text = "hello world"

field.selectedTextRange = range 
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.