iOS 응용 (SwiftUI)
[iOS - SwiftUI] 공유하기 기능 화면 구현 (UIActivityViewController, UIViewControllerRepresentable)
jake-kim
2022. 9. 23. 23:26
UIVeiwControllerRepresentable
- UIKit의 ViewController 타입을 SwiftUI의 View 타입으로 변경하여 사용할 수 있는 기능
- UIViewControllerRepresentable 프로토콜을 준수하는 구조체를 만들어서 사용
// UIViewControllerRepresentable 프로토콜
public protocol UIViewControllerRepresentable : View where Self.Body == Never {
associatedtype UIViewControllerType : UIViewController
func makeUIViewController(context: Self.Context) -> Self.UIViewControllerType
func updateUIViewController(_ uiViewController: Self.UIViewControllerType, context: Self.Context)
static func dismantleUIViewController(_ uiViewController: Self.UIViewControllerType, coordinator: Self.Coordinator)
associatedtype Coordinator = Void
func makeCoordinator() -> Self.Coordinator
typealias Context = UIViewControllerRepresentableContext<Self>
}
- makeUIViewController 메소드를 구현하여 사용
func makeUIViewController(
context: UIViewControllerRepresentableContext<ActivityViewController>
) -> UIActivityViewController {
// 구현
}
UIActivityViewController를 View로 변형
- ActivityViewController 구조체 생성
import Foundation
import SwiftUI
import UIKit
struct ActivityViewController: UIViewControllerRepresentable {
func makeUIViewController(context: UIViewControllerRepresentableContext<ActivityViewController>
) -> UIActivityViewController {
// TODO
}
func updateUIViewController(
_ uiViewController: UIActivityViewController,
context: UIViewControllerRepresentableContext<ActivityViewController>
) {}
}
- 필요한 프로퍼티 선언
- activityItems: UIImage와 같은 값을 넣어서 해당 아이템을 copy, aasign to contact, print... 등을 수행
- applicationActivities: 아래 그림과 같이 초록색 선 영역에 위치하는 아이템을 추가할 수 있는 기능
- presentationMode: 내부적으로 정의된 환경변수 (@Environment)에 있는 presentation값을 접근하여 현재의 ViewController를 액션이 동작되었을때 dismiss되도록 처리하기 위해 선언
var activityItems: [Any]
var applicationActivities: [UIActivity]? = nil
@Environment(\.presentationMode) var presentationMode

- makeUIViewController(context:)와 updateUIViewController(_:context:) 구현
func makeUIViewController(context: UIViewControllerRepresentableContext<ActivityViewController>
) -> UIActivityViewController {
let controller = UIActivityViewController(
activityItems: activityItems,
applicationActivities: applicationActivities
)
controller.completionWithItemsHandler = { (activityType, completed, returnedItems, error) in
self.presentationMode.wrappedValue.dismiss()
}
return controller
}
func updateUIViewController(
_ uiViewController: UIActivityViewController,
context: UIViewControllerRepresentableContext<ActivityViewController>
) {}
사용하는 쪽
- 일반 View처럼 사용
struct ContentView: View {
@State var isSharePresented = false
let image = UIImage(systemName: "star")
var body: some View {
Button("공유하기") {
self.isSharePresented = true
}
.sheet(
isPresented: $isSharePresented,
onDismiss: { print("Dismiss") },
content: { ActivityViewController(activityItems: [image]) }
)
}
}

* 전체 코드: https://github.com/JK0369/ExActivityViewController
* 참고