본문 바로가기
Swift

[SwiftUI 스터디] UIViewRepresentable: SwiftUI에 UIKit 뷰 연동!

by thekoon 2023. 10. 15.

https://developer.apple.com/documentation/swiftui/uiviewrepresentable

 

UIViewRepresentable | Apple Developer Documentation

A wrapper for a UIKit view that you use to integrate that view into your SwiftUI view hierarchy.

developer.apple.com

이전에 SwiftUI 프로젝트를 할때 이미지를 확대하고 스크롤하는 기능을 넣고 싶었는데

SwiftUI의 MagnificationGesture()가 저희가 일반적으로 사용하는 사진 확대 후 시점이동이 안되서

고민하던 중 UIKit의 뷰를 SwiftUI에 적용할 수 있는 UIViewRepresentable()를 알게 되었고, 간단하게 구현해보았습니다.

 

공식문서를 보면서 메서드를 하나씩 만들어가보겠습니다!

우선 간단히 표시할 SwiftUI 뷰를 하나 만들고, UITextField로 만들 CustomUITextField를 만들어줍니다

 

그리고 struct CustomUITextField: UIViewRepresentable {}를 만들면, 가장 먼저 입력해야할 게 typealias입니다

typealias UIViewType = UITextField

 

UIViewType을 아래 코드에서 따로 안 쓰는데 왜 필수적으로 설정해야되지? 했었는데

아래 함수를 구현할때 인풋, 리턴 타입을 UIViewType에 설정한 타입으로 알아서 설정되서 편리하더라구요!

 

- makeUIView(context: Context) -> UITextField

 

- updateUIView(_ uiView: UITextField, context: Context)

그리고 이 컨텐츠의 사이즈도 설정해줄 수 있었습니다.

- sizeThatFits(_ proposal: ProposedViewSize, uiView: UITextField, context: Context) -> CGSize?

 

이렇게 구현하고 테스트를 하기 위해 프리뷰를 봤는데요

이상하게 처음 텍스트필드에 "시작"이라고 값은 들어와있는데

내부의 텍스트를 바꿔도 inputText의 값 자체는 변하지 않아서

onChange메소드도 호출 안되고, Text에 표시된 값도 바뀌지 않았습니다.

 

그래서 알아보니

SwiftUI -> UIKit으로 데이터를 보낼땐 State - Binding

UIKit -> SwiftUI로 데이터를 보낼땐 Coordinator를 구현해서 보내야된다고 하더라구요,

여기서 Coordinator를 보니 UIKit에서 delegate를 채택하는 개념인 것 같았습니다.

 

makeCoordinator() -> Coordinator 함수를 만들어주고,

Coordinator Class를 구현해줍니다.

Coordinator class는 NSObject를 상속하고, 사용할 Delegate인 UITextFieldDelegate 프로토콜을 채택해야 합니다.

그리고 Coordinator 내에 delegate채택시 구현할 함수를 작성해줍니다.

 

그리고 꼭! delegate를 채택해주세요!!

 

이렇게 구현하고 다시 한번 실행해보니

 

 

이렇게 onChange메서드 내의 프린트 함수도 잘 실행되고,

Text의 input값도 바뀌어서 화면에 표시되는걸 알 수 있었습니다!

물론 delegate내에 구현된 Print도 잘 찍히네요ㅎㅎ

 

이번엔 연습하면서 간단하게 TextField로 구현해보았는데요,

다음에는 ScrollView로 PinchZoom이 되는 이미지뷰를 구현해보고 싶습니다!

핀치줌하고 스크롤하는게 생각보다 어렵더라구요

더 연습해보고 구현해보겠습니다! 화이팅 화이팅!!