UIViewRepresentable은 UIKit의 UIView를 SwiftUI로 쓸 수 있게 하는 방법 중하나
이렇게 간단한 건 금방 구현할 수 있는데
조금 더 복잡한 UIView가 된다면?
예를들어서 SwiftUI로 구현한 TextField같은 경우에 커스텀에 제한되어 있는 것들이 많다.
UITextField를 바꿔봅시다
똑같죠?
오케이 색깔 바꾸는 것까지는 했는데 여기 입력되는 값이 실제로 뷰를 업데이트 해야함
우선 바인딩할 수 있는 프로퍼티를 선언해주고
Coordinator를 만들어주고 Delegate를 채택해줌
그리고 makeCoordinator메소드로 Coordinator를 반환하게 해주고
makeUIView에서 textfield Delegate이 context의 coordinator가 되게 해줬다!
그럼 Coordinator 클래스에선 어떤 게 필요할까?
struct UITextFieldViewRepresentable: UIViewRepresentable {
@Binding var text: String
func makeUIView(context: Context) -> some UIView {
let textfield = getTextField()
textfield.delegate = context.coordinator
return textfield
}
func updateUIView(_ uiView: UIViewType, context: Context) {
}
private func getTextField() -> UITextField {
let textfield = UITextField(frame: .zero)
let placeholder = NSMutableAttributedString(string: "Type here...", attributes: [
.foregroundColor : UIColor.red
])
textfield.attributedPlaceholder = placeholder
return textfield
}
func makeCoordinator() -> Coordinator {
return Coordinator(text: $text)
}
class Coordinator: NSObject, UITextFieldDelegate {
@Binding var text: String
init(text: Binding<String>) {
self._text = text
}
func textFieldDidChangeSelection(_ textField: UITextField) {
text = textField.text ?? ""
}
}
}
Delegate에 해당하는 메소드를 구현해주고 Binding이 되게 해주면 끝!
근데 한가지 문제점이 있다!
UIKit타이핑할 땐 다 바인딩이 연결 되어있는데
SwiftUI타이핑할 때 UIKit이 연결되어 있지는 않음!!
Generic하게 mkaeUIView에서 반환되던 값을 UITextField로 명시해주고
updateUIView에서 SwiftUI가 uiView를 변할 수 있게 해줬다!
그러니까 아래와 같은 차이임
그리고 프로퍼티 뚫어서 바뀌게도 해줄 수 있음!
init에서 초기값줘서 인스턴스 생성할 때 초기값없으면 자동으로 입력되게도 해줄 수 있습니다~!
만약에 여기서 placeholder가 나중에 변경되어야 한다면?