Notice
Recent Posts
Recent Comments
Link
관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - SwiftUI] 공유하기 기능 화면 구현 (UIActivityViewController, UIViewControllerRepresentable) 본문

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

초록색 선 영역 - applicationActivities

  • 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

* 참고

https://developer.apple.com/forums/thread/709758

Comments