본문 바로가기

UIKit

[UIkit] 키보드 어보이던스(with 카카오톡 채팅방 만들기)

 

안녕하세요!

 

우리가 카카오톡을 사용할 때 아래 영상처럼 채팅을 치기 위해선 키보드(소프트)를 사용해야합니다.

 

카카오톡 채팅방

 

영상을 자세히 보시면 키보드가 채팅이 입력되는 공간을 가리지 않고 밀어내는 것을 확인할 수 있습니다.

 

이런 동작을 Keyboard Avoidance라고 합니다.

 

일전 SwiftUI를 사용하여 키보드 어보이던스를 피하는 글을 작성한 적이 있었는데요

 

UIKit같은 경우 SwiftUI와 달리 키보드 어보이던스가 자동으로 실행되지 않습니다.

(자동으로 키보드 어보이던스가 적용되는 SwiftUI는 해당 기능을 끄는 것이 까다롭습니다.. UIKit 최고 🙌)

 

아래 영상은 제가 직접 구현한 채팅창 화면입니다.

 

주니오스의 구현

 

먼저 입력영역은 UITextView로 구현하였습니다.

 

카카오톡같은 경우는 멀티라인 입력을 지원하기 때문에 한줄입력밖에 안되는 UITestField보단

 

UITextView가 적합하다고 판단하였습니다.

 

UITextView가 First responder가 되면 소프트 키보드가 화면상에 등장하게 됩니다.

 

해당 이벤트는 NotificationCenter를 사용하여 포착할 수 있습니다.

 

키보드 이벤트 캐칭

 

UIResponder.keyboardWillShowNotification의 경우 키보드가 등장하기전 호출되고 

 

UIResponder.keyboardWillHideNotification의 경우 키보드가 사라지기전 호출됩니다.

(First responder에서 해제될 때)

 

Notification정보를 통해서 키보드가 등장하는 애니메이션의 duration

 

키보드가 등장한 이후 키보드 Frame정보를 획들할 수 있습니다.

 

키보드 이벤트 세부정보

 

해당 정보들을 사용하여 입력창과 채팅내역을 보여주는 뷰를 원하는 만큼 밀어내는 방식을 사용했습니다.

 

밀어내는 방법으로는 transform을 사용하였습니다.

 

transform을 활용한 키보드 어보이던스

 

transform을 변형하는 경우 AutoLayout에 영향을 끼치지 않음으로

 

다른 뷰들에 영향을 주지않고 필요한 뷰에만 키보드 어보이던스를 적용할 수 있다는 장점이 있습니다.

 

 

 

UITextView

 

해당 예제를 구현하는데 가장 까다로웠던 것은 UITextView의 Inset들이였습니다.

 

우선 UITextView는 스크롤과 관련된 옵션이 존재합니다.

 

스크롤 기능을 사용하는 경우 내부적으로 instrinsicSize를 가지지 않아 레이아웃을 직접 설정해줘야 합니다.

 

스크롤을 사용하지 않는 경우 기본적으로 한줄크기의 기본 사이즈를 가지며, 라인이 증가될 수록 그 값도 커집니다.

 

텍스트 입력을 통해 자신의 크기 결정

 

 

텍스트 뷰는 contentInset, textContainerInset 두종류의 인셋을 사용할 수 있습니다.

 

contentInset는 내부 컨텐츠(스크롤 뷰 사용시)에 적용되는 인셋 입니다.

 

해당 인셋을 UITextView가 사용할 수 있는 이유는 UITextView가 UIScrollView를 상속하기 때문입니다.

UITextView: UIScrollView

 

contentInset은 텍스트 필드가 스크롤을 사용할 때 정상적으로 동작합니다.

 

만약 스크롤을 사요중이 아닌데 해당 값을 설정하는 경우 UI가 의도대로 동작하지 않습니다.

 

의도치 않게 아래로 내려간 텍스트 뷰

 

 

textContainerInset는 실제로 텍스트가 입력되는 요소와 텍스트 컨테이너간의 인셋입니다.

 

해당 값은 UITextView자체 프로퍼티로 스크롤 여부에 관계 없이 사용이 가능합니다.

 

안쪽에 빨간색 화살표는 lineFragmentPadding프로퍼티로 설정할 수 있으며, 기본값이 5입니다.

 

아래코드는 예시에 적용된 코드입니다.

실제로 사용한 인셋

 

예시 프로젝트 레포지토리를 남겨놓겠습니다.

 

Tuist로 구현한 프로젝트라 tuist generate후 돌려보시길 바랍니다 감사합니다~!

 

 

GitHub - J0onYEong/ChattingUI: 카카오톡과 라인의 채킹방을 참고한 채팅방 UI입니다.

카카오톡과 라인의 채킹방을 참고한 채팅방 UI입니다. Contribute to J0onYEong/ChattingUI development by creating an account on GitHub.

github.com

 

 

참고한 UITextView관련 포스팅입니다.

 

 

 

[iOS - swift] UITextView 패딩, 인셋 (lineFragmentPadding)

UITextView의 padding UITextView에는 padding이라는 개념과 inset 개념이 존재 inset은 3가지 (contentInset, textContainerInset, scrollIndicatorInsets) contentInset은 textContainer와 scrollView의 간격 textContainerInset은 텍스트와 con

ios-development.tistory.com

 

 

[iOS - swift] UITextView의 구조 (contentInset, textContainerInset, scrollIndicatorInsets)

UITextView 위 사진처럼 UITextView는 내부적으로 textInputView를 가지고 있는 형태 textInputView를 감싸고 있는 프로퍼티는 textContainer이므로, textInputView 내부의 inset을 조절하고 싶은 경우에는 `textContainerIns

ios-development.tistory.com