UIViewRepresentable을 이용하여 SwiftUI에서 UITextView를 사용하기
SwiftUI에는 multiline textfield가 없기 때문에 UIViewRepresentable을 이용하여 UIKit의 UITextView를 SwiftUI에서 사용할 수 있게 하는 방법을 배웁니다.
개요
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, text
와 font
를 만들고 인스턴의 속성을 설정하는데 이용합니다.
또한, UIKit 뷰의 델리게이트와 SwiftUI를 연결하는 역할을 하게 될coordinator
에 UITextView
의 delegate
를 설정합니다. 이 메서드에서 추가적으로 UITextView
의 원하는 스타일을 설정 할 수도 있습니다.
상태 업데이트
updateUIView(_:context:)
에서 UIKit 뷰의 상태를 업데이트합니다. SwiftUI의 TextView를 사용하는 곳에 text
와 font
의 상태 속성을 다음과 같이 선언하고 바인딩하면 프레임워크는 자동으로 updateUIView(_:context:)
를 호출하여 뷰 구성을 업데이트합니다.
Coordinator 만들기
UIKit에서 델리게이트로 작업하고 SwiftUI와 다시 통신해야하는 경우 makeCoordinator()
를 구현하고 Coordinator
인스턴스를 제공해야 합니다. TextView
구조체 내부에 Coordinator
클래스를 선언하고 다음과 같이 작성합니다.
위에서 UITextView
의 delegate
를 Coordinator
로 설정하였으므로, 사용자가 텍스트를 변경할 때마다 Coordinator
가 채택한 UITextViewDelegate
의 메서드 textViewDidChange(_:)
가 호출됩니다. 이 때마다 바인딩 속성 text
의 wrappedValue
를 업데이트 하여 SwiftUI로 다시 전달합니다.
마치며
SwiftUI가 버전업을 거듭하게 되면 multiline을 지원하는 textfield 및 지금까지 제공되지 못하고 있는 표준 UI 구성요소들이 전부 지원될 것이라 생각합니다. 그 전까지는 UIViewRepresentable
를 이용하여 UIKit 뷰와 SwiftUI를 통합하여 사용하고 있으면 될 것 같습니다.