[iOS] UIScrollView + UITextView 마지막 텍스트 짤리는 현상



# UIScrollView + UITextView 마지막 텍스트 짤리는 현상

안녕하세요 __물먹고하자__ 입니다 :)
출시했던 앱에서 발생한건으로 운영하면서 딱히 문제가 나오진 않았었는데
유독 iOS18이후로 하나 둘씩 문제가 발생하고 있네요. __(해당부분은 iOS16에서도 동일하게 발생했음)__
이슈가 되었던 부분과 해결과정, 해결했던 내용 공유드립니다.

---
## 1. UIScrollView + UITextView 사용했던 이유? 문제는?
> 💡 내용(String) 부분을 보여주는 화면 줌 In/Out 기능을 사용하고 있는중.
- __문제는?__ 전부 짤리는것도 아니며, __긴 링크__ 뒤에 띄어쓰기 후 들어간 __텍스트__가 안보이는현상
- ex) __https://.......(생략)....... 텍스트영역__

<!-- 1.PC 버전이미지 -->
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvFw2Fd9VH_QNHrn9NnkBf_W08GAB6V8VFp19F0lZiPpUDNB0ibZs4z4ySPHBEnD1JhVyGppUfg_4rr66tgRR87BLZJDNFY5uvOPS-P-fjLs_IqtyOUxLEIHgdvFlwjPbglapIi9Gu_EcOyYc3b_ia3HdsFFj3pJfJHaRKTmJi-ZHoYOfT44KNWY6Y2LfI/s1916/1%29%E1%84%86%E1%85%A6%E1%84%89%E1%85%B5%E1%86%AB%E1%84%8C%E1%85%A5%E1%84%8B%E1%85%A6%E1%84%89%E1%85%A5_%E1%84%82%E1%85%A9%E1%84%8E%E1%85%AE%E1%86%AF.png" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" data-original-height="1526" data-original-width="1916" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvFw2Fd9VH_QNHrn9NnkBf_W08GAB6V8VFp19F0lZiPpUDNB0ibZs4z4ySPHBEnD1JhVyGppUfg_4rr66tgRR87BLZJDNFY5uvOPS-P-fjLs_IqtyOUxLEIHgdvFlwjPbglapIi9Gu_EcOyYc3b_ia3HdsFFj3pJfJHaRKTmJi-ZHoYOfT44KNWY6Y2LfI/s600/1%29%E1%84%86%E1%85%A6%E1%84%89%E1%85%B5%E1%86%AB%E1%84%8C%E1%85%A5%E1%84%8B%E1%85%A6%E1%84%89%E1%85%A5_%E1%84%82%E1%85%A9%E1%84%8E%E1%85%AE%E1%86%AF.png" width="600"/></a></div>
* PC 버전에서 보이는 링크 + 텍스트 영역 __"아마링크 포함전송(이게 문제껀)"__ 보임

<!-- 2.아이폰이미지 -->
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0DKdh53bCLWGQv5N8MikSz-B00merw6s1fcewr918PbbVJ_I3rOEpR6nZ0tRGu0uOWKjbVLqH3NcoB78XGgNLN3K_K4v3Iu2hylN0trhlwcT3ayV7rmv-7xP7Bk8jY0ts-RvAr7YGdlnHsD1nGHKOFbJcFyQgZe9f86UloNnVxXOOFJh_HjTjWAn92FtO/s2622/2%29iPhone%E1%84%8B%E1%85%A6%E1%84%89%E1%85%A5_%E1%84%82%E1%85%A9%E1%84%8E%E1%85%AE%E1%86%AF.png" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" data-original-height="2622" data-original-width="1206" height="600" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0DKdh53bCLWGQv5N8MikSz-B00merw6s1fcewr918PbbVJ_I3rOEpR6nZ0tRGu0uOWKjbVLqH3NcoB78XGgNLN3K_K4v3Iu2hylN0trhlwcT3ayV7rmv-7xP7Bk8jY0ts-RvAr7YGdlnHsD1nGHKOFbJcFyQgZe9f86UloNnVxXOOFJh_HjTjWAn92FtO/s600/2%29iPhone%E1%84%8B%E1%85%A6%E1%84%89%E1%85%A5_%E1%84%82%E1%85%A9%E1%84%8E%E1%85%AE%E1%86%AF.png"/></a></div>
* 아이폰에서 링크 + 텍스트 영역 __"아마링크 포함전송(이게 문제껀)"__ 짤림


---
## 2. Xcode 디버그 확인, UITextView 단독으로 쓰면?
>💡 __실험1) ScrollView + UITextView => UITextView 만 사용시__ : 정상적으로 노출됨(짤림현상없음)
💡 __실험2) ScrollView + UITextView 디버그 해보자__ : 마지막 텍스트영역이 잡히지 않음

실험을 진행하다가 여기에서 __방향성에 대한고민__을 하게 되었는데,
UITextView __단독으로 사용시 정상__, UISCrollView + UITextView 사용시 __특정 길이에서만 문제__

__방안1)__ Link 뒤에 텍스트가 온다면 __강제개행을 넣는다? (원본 훼손)__
__방안2)__ UITextView만 사용하고, __줌 기능을 핀치줌을 통해 Font를 키운다? (의도X)__
__방안3)__ UIScrollView + UITextView 어떻게든 살린다.. __(막막함)__

<!-- 3. 3D 체크부분 -->
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWv1TaM0Wj08dGl3EaPgDNBwvJ5vTGjbj37NMhWVxrdG463CSRJNCc7H4BWEKly-zegGRKOejZMBoPq2n6IbLnql57tZv3GnYYz5jGTV11F65FtUaK3sZ8nOKlJ-dnTHkaxiUAm_6df9sjsZFKZUKWN-qffFNKwFQcz49hz_FSFPQO-yFbnm7LH61OPP_V/s1974/3%293d%E1%84%8E%E1%85%A6%E1%84%8F%E1%85%B3.png" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" data-original-height="1974" data-original-width="1284" height="600" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWv1TaM0Wj08dGl3EaPgDNBwvJ5vTGjbj37NMhWVxrdG463CSRJNCc7H4BWEKly-zegGRKOejZMBoPq2n6IbLnql57tZv3GnYYz5jGTV11F65FtUaK3sZ8nOKlJ-dnTHkaxiUAm_6df9sjsZFKZUKWN-qffFNKwFQcz49hz_FSFPQO-yFbnm7LH61OPP_V/s600/3%293d%E1%84%8E%E1%85%A6%E1%84%8F%E1%85%B3.png"/></a></div>
* 링크영역까지는 UITextView에서 잡혔는데, __마지막 텍스트의 위치가 렌더링 되지 않음__

* __방안2__를 만들었었는데, 의도부분에서 원치 않는다는 의견이 많아 결국 __방안3__ 을 채텍

---
## 3. 왜? UITextView 단독으로 썼을때는 나온것일까?
* UITextView 내부의 ScrollView에서 __1.링크__ 렌더링 후 __2.텍스트__를 렌더링을 해서 contentSize가 갱신되는걸로 추측됨
* 예상되는 문제점은 UITextView에서 __1.링크__ 렌더링 후 contentSize가 껍데기 UISCrollView에 맞춰지고, 이후 __2.텍스트__를 렌더링 되려고 했지만 Size가 맞지 않는건가? (여기까진 추측)

---
## 4. UIScrollView + UITextView 포기는 못하고 비슷한 사례?
>💡 유사사례 : <a href="https://stackoverflow.com/questions/33427068/scroll-to-the-bottom-of-textview-programmatically" target="_blank">https://stackoverflow.com/questions/33427068/scroll-to-the-bottom-of-textview-programmatically</a>
💡 UITextView.layoutManager.allowsNonContiguousLayout = false 처리후 정상적으로 보인다는 글
💡 참고 : <a href="https://developer.apple.com/documentation/appkit/nslayoutmanager/allowsnoncontiguouslayout" target="_blank">allowsNonContiguousLayout</a>

<!-- 4. 해결? -->
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh51WepkspIYnuruV8ezWB4W-j_THI3_7f6vdemGAvlHCauT1wOGaniCBSfrm-uUdFy6ui4eBGgN499QmyjQSF1HqYW_keHcUaLPyajD8ASMJcMDfXfq8M8LkQL5WPHWHfLlsSjSZGHeyp8cq12fmWU22VKNAUEO3i0pqf1MbQbj9wNFWi3SrrvFckquh0U/s2868/9%29%E1%84%92%E1%85%A2%E1%84%80%E1%85%A7%E1%86%AF.jpeg" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" data-original-height="2868" data-original-width="1320" height="600" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh51WepkspIYnuruV8ezWB4W-j_THI3_7f6vdemGAvlHCauT1wOGaniCBSfrm-uUdFy6ui4eBGgN499QmyjQSF1HqYW_keHcUaLPyajD8ASMJcMDfXfq8M8LkQL5WPHWHfLlsSjSZGHeyp8cq12fmWU22VKNAUEO3i0pqf1MbQbj9wNFWi3SrrvFckquh0U/s600/9%29%E1%84%92%E1%85%A2%E1%84%80%E1%85%A7%E1%86%AF.jpeg"/></a></div>
* __UITextView.layoutManager.allowsNonContiguousLayout = false__
* 옵션값을 넣으니 갑자기 __정상표현__이 되었다?!

allowsNonContiguousLayout 보통.. __기본값이 false 일것 같아서__ 디버그 멈추고, 값 넣기 전에 디버그로 찍어보았는데, __이상한점 발견__

<!-- allowsNonContiguousLayout옵션값 -->
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvB2ce23vj984DJjZgtB5Ju44Bqn1OApO41JrAiv5hoxp0UwGLU-dTbQYTn49K0B6lmLtW7lqSFYcJIEM14F_JS1IIysmtUm8VjHkebWLNXIbqnhGdDEKsNXGXKVyFNSrNwvlMbK3sQqQ5bipTIxevH1VkvXXPt-AfOCC8QZzWRPpCA8mawlbGy01JrNOs/s1338/5%29%E1%84%8B%E1%85%A9%E1%86%B8%E1%84%89%E1%85%A7%E1%86%AB%E1%84%80%E1%85%A1%E1%86%B9%E1%84%8E%E1%85%A6%E1%84%8F%E1%85%B3.png" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" data-original-height="486" data-original-width="1338" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvB2ce23vj984DJjZgtB5Ju44Bqn1OApO41JrAiv5hoxp0UwGLU-dTbQYTn49K0B6lmLtW7lqSFYcJIEM14F_JS1IIysmtUm8VjHkebWLNXIbqnhGdDEKsNXGXKVyFNSrNwvlMbK3sQqQ5bipTIxevH1VkvXXPt-AfOCC8QZzWRPpCA8mawlbGy01JrNOs/s600/5%29%E1%84%8B%E1%85%A9%E1%86%B8%E1%84%89%E1%85%A7%E1%86%AB%E1%84%80%E1%85%A1%E1%86%B9%E1%84%8E%E1%85%A6%E1%84%8F%E1%85%B3.png" width="600"/></a></div>
* 찍힌내용을보면 __layoutManager 사용하면 TextKit1로 스위칭된다.__
* 그렇다면 __allowsNonContiguousLayout__ 옵션설정이 아닌 TextKit1로 지정을 해도 동일하다는 소리

<!-- xib Textkit1 설정 -->
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdDtCbRy6TKv4ploITXOiginX0QczqiBQ7_DfGQjqszbeDfnxX2C0pnsvujFbu_W5fXmAa1XvmCMJ420I9WvuNe9jNu-HdhABJ2HM4ke0aXfKievJoG5-CWJLHXrRcUpJ_yGO6oYkO4WYZy34FWc5g9-P-p1Q0otwJrdo-Jt_i7tW58p1Ava9Gdwo8Nhka/s950/6%29TextKit%E1%84%87%E1%85%A7%E1%86%AB%E1%84%80%E1%85%A7%E1%86%BC.png" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" data-original-height="950" data-original-width="520" height="600" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdDtCbRy6TKv4ploITXOiginX0QczqiBQ7_DfGQjqszbeDfnxX2C0pnsvujFbu_W5fXmAa1XvmCMJ420I9WvuNe9jNu-HdhABJ2HM4ke0aXfKievJoG5-CWJLHXrRcUpJ_yGO6oYkO4WYZy34FWc5g9-P-p1Q0otwJrdo-Jt_i7tW58p1Ava9Gdwo8Nhka/s600/6%29TextKit%E1%84%87%E1%85%A7%E1%86%AB%E1%84%80%E1%85%A7%E1%86%BC.png"/></a></div>
* __역시 동일하게 잘 표현되고 있다.__ (언제나 그렇지만 힘들게 실험한건 간단하게 끝날때가 많다)

---
## #. TextKit1, TextKit2 무슨 차이가 나서 이런걸까?
>💡 __렌더링부분에 대한건 체감상__ 알겠고, 디테일한 부분은 정확히 몰라서 검색한부분 메모
| 구분               | TextKit 1                 | TextKit 2                     |
| :---------------- | :------------------ | :-------------------------- |
| 기본 사용 방식    | `layoutManager` 사용      | `NSTextLayoutManager` 사용     |
| 레이아웃 방식     | __줄 단위 레이아웃__ | __블록 단위 레이아웃__  |
| `allowsNonContiguousLayout` 설정 | 가능 (`true/false` 변경 가능) | 직접 설정 불가능 (기본적으로 `false`) |
| 성능              | __긴 문서에서 성능 저하 가능__ | __최적화된 메모리 사용으로 성능 향상__ |
| 렌더링 방식       | __수동 레이아웃 필요__        | __자동 동적 레이아웃__|
| iOS 지원 버전     | iOS 7 이상               | iOS 15 이상                   |


---
## 마무리
오랜만에 찾는 과정이 힘들었던 건이였네요.
솔직히 지금도 UITextView의 __TextKit1, TextKit2 렌더링 방식__이 틀리다라는점
빼고는 TextKit2에서도 안될 이유가 없어보이는데... 라는 생각이 드네요.

__UITextView에 딥하게 작업__을 하는게 아니다 보니, 간단하게 __TextKit1__ 방식으로 변경하여 해결했네요.

오늘은 이만~

즐거운 코딩 되게요.

끝.


댓글