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


109

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

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

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

답변:


316

다음 내용은 UITextField및 UITextView.

유용한 정보

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

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.