UIViewRepresentable을 이용하여 SwiftUI에서 UITextView를 사용하기

SwiftUI에는 multiline textfield가 없기 때문에 UIViewRepresentable을 이용하여 UIKit의 UITextView를 SwiftUI에서 사용할 수 있게 하는 방법을 배웁니다.

Munok Kim
4 min readAug 2, 2020
Photo by Morgan Housel on Unsplash

개요

SwiftUI에는 multiline textfield가 없기 때문에 UIViewRepresentable프로토콜을 사용하여 UIKit의 UITextView를 SwiftUI에서사용할 수 있게 해야 합니다. SwiftUI에서는 UIKit의 뷰를 사용하기 위해 UIViewRepresentable 프로토콜로 뷰를 랩핑 할 수 있습니다.

프로토콜 채택

커스텀 뷰 구조체를 생성하고 UIViewRepresentable 프로토콜을 채택합니다. UIViewRepresentable 프로토콜의 필요 메소드 3가지 makeUIView(context:), updateUIView(_:context:) 그리고 makeCoordinator()를 구현해야 합니다.

UIView 만들기

makeUIView(context:)에서 UITextView의 인스턴스를 반환하면 UIKit의 뷰를 래핑하여 SwiftUI에서 사용할 수 있습니다. UITextView의 인스턴스에 대한 두 가지의 커스텀 wrapper, textfont를 만들고 인스턴의 속성을 설정하는데 이용합니다.

또한, UIKit 뷰의 델리게이트와 SwiftUI를 연결하는 역할을 하게 될coordinatorUITextViewdelegate를 설정합니다. 이 메서드에서 추가적으로 UITextView의 원하는 스타일을 설정 할 수도 있습니다.

상태 업데이트

updateUIView(_:context:)에서 UIKit 뷰의 상태를 업데이트합니다. SwiftUI의 TextView를 사용하는 곳에 textfont의 상태 속성을 다음과 같이 선언하고 바인딩하면 프레임워크는 자동으로 updateUIView(_:context:)를 호출하여 뷰 구성을 업데이트합니다.

Coordinator 만들기

UIKit에서 델리게이트로 작업하고 SwiftUI와 다시 통신해야하는 경우 makeCoordinator()를 구현하고 Coordinator인스턴스를 제공해야 합니다. TextView 구조체 내부에 Coordinator 클래스를 선언하고 다음과 같이 작성합니다.

위에서 UITextViewdelegateCoordinator로 설정하였으므로, 사용자가 텍스트를 변경할 때마다 Coordinator가 채택한 UITextViewDelegate의 메서드 textViewDidChange(_:)가 호출됩니다. 이 때마다 바인딩 속성 textwrappedValue를 업데이트 하여 SwiftUI로 다시 전달합니다.

마치며

SwiftUI가 버전업을 거듭하게 되면 multiline을 지원하는 textfield 및 지금까지 제공되지 못하고 있는 표준 UI 구성요소들이 전부 지원될 것이라 생각합니다. 그 전까지는 UIViewRepresentable를 이용하여 UIKit 뷰와 SwiftUI를 통합하여 사용하고 있으면 될 것 같습니다.

--

--

Munok Kim

앱 깎는 장인이 되고 싶은 iOS 개발자입니다