Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- uiscrollview
- ribs
- Refactoring
- HIG
- 스위프트
- clean architecture
- 리펙터링
- 클린 코드
- ios
- 리팩토링
- Xcode
- uitableview
- tableView
- Observable
- Protocol
- RxCocoa
- Clean Code
- UITextView
- swift documentation
- UICollectionView
- 리펙토링
- swiftUI
- combine
- map
- 애니메이션
- SWIFT
- MVVM
- rxswift
- Human interface guide
- collectionview
Archives
- Today
- Total
김종권의 iOS 앱 개발 알아가기
[iOS - swift] 3. 붙여넣기 글자 제한 UITextView 처리, 커서 이동 처리 방법 - isScrollEnabled=false인 상태에서 커서 위치로 스크롤링 방법 (#caretRect(for:), #scrollToCursor) 본문
iOS 응용 (swift)
[iOS - swift] 3. 붙여넣기 글자 제한 UITextView 처리, 커서 이동 처리 방법 - isScrollEnabled=false인 상태에서 커서 위치로 스크롤링 방법 (#caretRect(for:), #scrollToCursor)
jake-kim 2023. 10. 15. 01:331. 붙여넣기 글자 제한 UITextView 처리, 커서 이동 처리 방법 - 단순 텍스트
2. 붙여넣기 글자 제한 UITextView 처리, 커서 이동 처리 방법 - UTF16 (이모지를 고려한 처리)
3. 붙여넣기 글자 제한 UITextView 처리, 커서 이동 처리 방법 - isScrollEnabled=false인 상태에서 커서 위치로 스크롤링 방법(#caretRect(for:), #scrollToCursor)
UITextView에서 cursor 영역으로 스크롤 이동시키는 방법
- 보통 UITextView의 isScrollEnabled = true로 하고 붙여넣기하면 해당 커서로 자동으로 스크롤 되지만, isScrollEnabled = false로 하고 외부 스크롤 뷰를 사용할 땐 외부 스크롤 뷰를 cursor로 이동시키는 작업이 따로 필요
- 아이디어
- textView.selectedTextRange를 사용하여 커서 위치 획득
- textView.caretRect(for:) 사용하여 커서 위치의 CGRect값 획득
- textView.convert(_:to:)를 사용하여 커서 위치가 UIScrollView 기준 상대 좌표로 변환
- scrollView.scrollRectToVisible()를 사용하여 스크롤 이동
구현
- 예제 UI 준비
- UIScrollView안에 UIStackView가 있는 형태
- UIStackView에 label과 textView를 삽입
private let scrollView = {
let view = UIScrollView()
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
private let stackView = {
let stackView = UIStackView()
stackView.axis = .vertical
stackView.translatesAutoresizingMaskIntoConstraints = false
return stackView
}()
private let textView = {
let view = UITextView()
view.textColor = .black
view.backgroundColor = .lightGray
view.isScrollEnabled = false
view.font = .systemFont(ofSize: 34)
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
private let label: UILabel = {
let label = UILabel()
label.text = "0/0"
label.textColor = .blue
label.font = .systemFont(ofSize: 24, weight: .regular)
label.numberOfLines = 0
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
- 입력한 문자열이 정해지는 UITextView 델리게이트 메소드, shouldChangeTextIn에서 처리 스크롤링
- 붙여넣기 여부 체크
extension ViewController: UITextViewDelegate {
func textView(
_ textView: UITextView,
shouldChangeTextIn range: NSRange,
replacementText text: String
) -> Bool {
...
let isPasted = 1 < text.count
...
}
}
- 붙여넣기인 경우, cursor가 이동되는데 딜레이가 있으므로 0.3초 후에 스크롤 되도록 구현
if isPasted {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
self.scrollView.scrollToCursor(in: textView)
}
}
extension UIScrollView {
func scrollToCursor(in textView: UITextView) {
// TODO
}
}
- 커서로 이동시키는 코드 추가
- textView.selectedTextRange를 사용하여 커서 위치 획득
- textView.caretRect(for:) 사용하여 커서 위치의 CGRect값 획득
- textView.convert(_:to:)를 사용하여 커서 위치가 UIScrollView 기준 상대 좌표로 변환
- scrollView.scrollRectToVisible()를 사용하여 스크롤 이동
func scrollToCursor(in textView: UITextView) {
// 커서 위치를 가져옴
guard let selectedRange = textView.selectedTextRange else { return }
// 커서 위치를 화면 좌표로 변환 (caret: 텍스트 커서를 의미)
let cursorRect = textView.caretRect(for: selectedRange.start)
// 커서 위치가 화면에 보이는 rect 영역 가져옴
let cursorRectInScrollView = textView.convert(cursorRect, to: self)
let visibleRect = CGRect(x: 0, y: contentOffset.y, width: bounds.size.width, height: bounds.size.height)
if !visibleRect.contains(cursorRectInScrollView.origin) {
// 커서 위치가 화면에 보이지 않으면 스크롤
scrollRectToVisible(cursorRectInScrollView, animated: true)
}
}
(완성)
'iOS 응용 (swift)' 카테고리의 다른 글
Comments