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 |
Tags
- collectionview
- UITextView
- Xcode
- Protocol
- 클린 코드
- HIG
- MVVM
- Observable
- 리펙터링
- UICollectionView
- swift documentation
- 애니메이션
- combine
- Clean Code
- Human interface guide
- uitableview
- rxswift
- uiscrollview
- 스위프트
- 리팩토링
- ribs
- 리펙토링
- swiftUI
- ios
- Refactoring
- tableView
- RxCocoa
- SWIFT
- clean architecture
- map
Archives
- Today
- Total
김종권의 iOS 앱 개발 알아가기
[iOS - swift] iOS16+ UITextView 입력 중 위로 스크롤 되는 버그 해결 방법 (최신) (UIScrollView, UIStackView, UITextView) 본문
iOS 응용 (swift)
[iOS - swift] iOS16+ UITextView 입력 중 위로 스크롤 되는 버그 해결 방법 (최신) (UIScrollView, UIStackView, UITextView)
jake-kim 2023. 11. 18. 01:19UITextView 입력 중 위로 스크롤 되는 현상
- UIStackView를 사용하여 리스트 형태의 뷰를 보여줄 때 중간에 UITextView가 있다면 버그가 발생
- 뷰형태: UIScrollView안에 UIStackView을 넣고, 이 스택뷰에 UITextView 넣어서 리스트 형태의 뷰를 만든 형태
- (UITextView의 isScrollEnabled는 false로 설정)
ex) 뷰 형태
import UIKit
class ViewController: UIViewController {
private let scrollView = UIScrollView()
private let stackView = UIScrollView()
private let textView = UITextView()
private let button = UIButton()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(scrollView)
scrollView.addSubview(stackView)
stackView.addArrangedSubview(textView)
stackView.addArrangedSubview(button)
NSLayoutConstraint.activate([
scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
scrollView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
scrollView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor)
])
NSLayoutConstraint.activate([
stackView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor),
stackView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor),
stackView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor),
stackView.topAnchor.constraint(equalTo: scrollView.topAnchor),
stackView.widthAnchor.constraint(equalToConstant: UIScreen.main.bounds.width)
])
}
}
iOS16부터 생겨난 버그 - 스크롤이 위로 튕기는 현상
- 1) 텍스트 하단 우측에서 텍스트를 입력할 때 다음줄로 넘어가는 케이스
- 2) 이모지 왼쪽에 문자 입력하는 케이스
- 3) 이모지 왼쪽에 커서두고 키보드에서 한영 <-> 이모지 변경하는 케이스
해결 방법
- UITextView를 서브 클래싱하여 SelfSizingTextView 구현
- SelfSizing 뷰 구현 개념은 이전 포스팅 글 참고
- 이유) UITextView 레이아웃 계산을 내부적으로 잘못하여 스크롤이 위로 튕기는 것으로 예측하여 SelfSizing을 사용
class SelfSizingTextView: UITextView {
override var intrinsicContentSize: CGSize {
contentSize
}
override func layoutSubviews() {
invalidateIntrinsicContentSize()
super.layoutSubviews()
}
}
- 이 textView를 사용하여 isScollEnabled를 true로 설정
private let textView = {
...
textView.isScrollEnabled = true
...
return t
}()
결과)
- 입력할 때 자동으로 스크롤이 안되는 현상이 존재
- -> scrollToCursor를 사용하여 입력되는 동시에 스크롤이 해당 지점으로 스크롤되게끔 수동으로 지정
- scrollToCursor 개념은 이전 포스팅 글 참고
extension ViewController: UITextViewDelegate {
func textViewDidChange(_ textView: UITextView) {
scrollView.scrollToCursor(in: textView)
}
}
extension UIScrollView {
func scrollToCursor(in textView: UITextView) {
guard let selectedRange = textView.selectedTextRange else { return }
let cursorRect = textView.caretRect(for: selectedRange.start)
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