[SwiftUI Mater] #13 UIView Representable

Woozoo·2023년 4월 2일
0

[SwiftUI Review]

목록 보기
28/41
post-custom-banner

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가 나중에 변경되어야 한다면?


profile
우주형
post-custom-banner

0개의 댓글