-
ScreenShot(Save, Share)오늘의 Swift 상식 2021. 10. 22. 17:32728x90반응형
안녕하세요. iOS 개발자 에이든입니다!👦🏻
☕️스타벅스, 🚕카카오택시 등 우리가 자주 사용하는 App들의 영수증을 저장해 보고 공유하신 적 있으신가요?
저는 회사에 영수증 제출할 때 그 기능을 많이 써본 것 같아요ㅎㅎㅎㅎ
무언가를 구매하는 App들에는 이런 기능들이 자주 사용되는데
오늘은 이 기능에 대한 내용을 공유하고자 합니당ㅋㅋㅋㅋㅋ
늘 그렇듯 코드는 SwiftUI 기준이고, ViewController를 사용하시는 분들은
하단 코드에 View를 Extension 하는 과정 없이 바로 UIView에 적용시키면 됩니다!
그럼 시~~~~~작!
ScreenShot
일단! 우리가 스크린샷을 찍고 저장까지 할 거니깐!
권한부터 설정해줍시다!
Xcode13부터는 Info.plist가 TARGETS 내부로 이동했죠!
Info로 가서
Privacy - Photo Library Usage Description을 추가해주고
왜 권한이 필요한지 설명을 달아줍시당!
일단 코드를 좀 더 깔끔하고, 수정하기 쉽도록
ScreenShot 기능을 UIView, View에 Extension으로 Method를 만들어 주겠습니다!
ViewController를 사용하시는 분은 UIView만 하시면 됩니당!
먼저 ScreenShot을 찍기 위해선 UIGraphicsBeginImageContextWithOptions(_:_:_:)로 Option들을 정해주고,
UIGraphicsGetCurrentContext()를 사용하여 현재 Context를 가져온 뒤 UIGraphicsGetImageFromCurrentImageContext()로 현재의 Context를 UIImage로 변환하면 현재의 최 상단에 있는 View를 UIImage로 뽑을 수 있게 됩니다!
func UIGraphicsBeginImageContextWithOptions(_ size: CGSize, _ opaque: Bool, _ scale: CGFloat)
∙ size: 갤러리에 저장할 이미지
∙ opaque: 불투도. 완전히 불투명하면 true, 부분적으로 투명하면 false이고 알파값이 들어가야 합니다.
∙ scale: 배율// UIView에 ScreenShot을 넣기 위함 extension UIView { var screenShot: UIImage { let rect = self.bounds UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0) let context: CGContext = UIGraphicsGetCurrentContext()! self.layer.render(in: context) let capturedImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()! return capturedImage } } // View에 ScreenShot을 넣기 위함 extension View { func takeScreenshot(origin: CGPoint, size: CGSize) -> UIImage { let window = UIWindow(frame: CGRect(origin: origin, size: size)) // UIHostingController: SwiftUI View들을 관리하기 위한 ViewController let hosting = UIHostingController(rootView: self) hosting.view.frame = window.frame window.addSubview(hosting.view) window.makeKeyAndVisible() return hosting.view.screenShot } }
갤러리에 저장하기
UIImageWriteToSavedPhotosAlbum(_:_:_:_:)를 사용하면 바로 갤러리에 이미지를 저장할 수 있습니다!
func UIImageWriteToSavedPhotosAlbum(_ image: UIImage, _ completionTarget: Any?, _ completionSelector: Selector?, _ contextInfo: UnsafeMutableRawPointer?)
∙ image: 갤러리에 저장할 이미지
∙completionTarget: Call Back 받을 Object
∙completionSelector: Call Back Method
∙contextInfo: completionSelector에 전달할 정보func screenShot() { let screenshot = body.takeScreenshot(origin: UIScreen.main.bounds.origin, size: UIScreen.main.bounds.size) // 사진권한이 허용 되어 있으면 저장 PHPhotoLibrary.requestAuthorization( { status in switch status { case .authorized: UIImageWriteToSavedPhotosAlbum(screenshot, self, nil, nil) showingAlert = true case .denied: break case .restricted, .notDetermined: break default: break } }) }
공유하기
이 녀석은 UIActivityViewController로 공유 및 복사 등 다양한 작업을 할 수 있는 ViewController를 띄웁니다. 그래서 공유를 하고 싶으면 이 녀석만 호출해서 띄우면 끝!
func share() { let screenshot = body.takeScreenshot(origin: UIScreen.main.bounds.origin, size: UIScreen.main.bounds.size) let activityViewController = UIActivityViewController(activityItems: [screenshot], applicationActivities: nil) UIApplication.shared.windows.first?.rootViewController?.present(activityViewController, animated: true) }
전체 Code, 결과
import SwiftUI import Photos // PHPhotoLibrary를 활용해서 갤러리 권한은 확인하기 위함 struct ContentView: View { // MARK: Property @State private var showingAlert: Bool = false // MARK: View var body: some View { VStack { ZStack { HStack(alignment: .center) { Spacer() Image(systemName: "square.and.arrow.down") .resizable() .aspectRatio(contentMode: .fit) .frame(width: 25, height: 25, alignment: .center) .onTapGesture { screenShot() } Spacer().frame(width: 15) Image(systemName: "square.and.arrow.up") .resizable() .aspectRatio(contentMode: .fit) .frame(width: 25, height: 25, alignment: .center) .onTapGesture { share() } Spacer().frame(width: 20) } .frame(height: 34) Text("스크린샷 및 공유") } .padding(EdgeInsets(top: 5, leading: 0, bottom: 0, trailing: 0)) Divider() .frame(width: UIScreen.main.bounds.width, height: 1, alignment: .center) .background(Color.gray) .opacity(0.3) VStack { Spacer() Image(systemName: "airtag.fill") .resizable() .aspectRatio(contentMode: .fit) .frame(width: 250, height: 250, alignment: .center) .foregroundColor(.white) Spacer() } .frame(width: UIScreen.main.bounds.width) .background(Color.black.ignoresSafeArea(edges: [.leading, .trailing, .bottom])) } .background(Color.white) .alert(isPresented: $showingAlert) { Alert(title: Text("저장 완료"), message: Text("스크린샷이 저장되었습니다."), dismissButton: .default(Text("확인"))) } } } extension ContentView { /// 이미지 저장 func screenShot() { let screenshot = body.takeScreenshot(origin: UIScreen.main.bounds.origin, size: UIScreen.main.bounds.size) UIImageWriteToSavedPhotosAlbum(screenshot, self, nil, nil) // 사진권한이 허용 되어 있으면 저장 PHPhotoLibrary.requestAuthorization( { status in switch status { case .authorized: showingAlert = true case .denied: break case .restricted, .notDetermined: break default: break } }) } /// 이미지 공유 func share() { let screenshot = body.takeScreenshot(origin: UIScreen.main.bounds.origin, size: UIScreen.main.bounds.size) let activityViewController = UIActivityViewController(activityItems: [screenshot], applicationActivities: nil) UIApplication.shared.windows.first?.rootViewController?.present(activityViewController, animated: true) } } // UIView에 ScreenShot을 넣기 위함 extension UIView { var screenShot: UIImage { let rect = self.bounds UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0) let context: CGContext = UIGraphicsGetCurrentContext()! self.layer.render(in: context) let capturedImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()! return capturedImage } } // View에 ScreenShot을 넣기 위함 extension View { func takeScreenshot(origin: CGPoint, size: CGSize) -> UIImage { let window = UIWindow(frame: CGRect(origin: origin, size: size)) let hosting = UIHostingController(rootView: self) hosting.view.frame = window.frame window.addSubview(hosting.view) window.makeKeyAndVisible() return hosting.view.screenShot } }
🖼 갤러리에 저장하기 🖼
👨👩👦👦 공유하기 👨👩👦👦
오늘은 화면 ScreenShot과 이를 저장하고, 공유하는 법에 대해 알아보았습니당!
이것만 했는데도 뭔가 있어 보이네요ㅎㅎㅎㅎㅎ
공유하는 건 UIActivityController 하나만 띄워도 다양한 기능을 활용할 수 있으니 편리해서 넘 좋..🥺
혹시라도 부족하거나 잘못된 부분 그리고 질문 있으시면 언제든 댓글 부탁드려요! 감사합니다!👦🏻👋🏻
728x90반응형'오늘의 Swift 상식' 카테고리의 다른 글
QR code - Scan! (0) 2021.09.21 QR Code - 만들기편! (0) 2021.09.15 Protocol 2편 (Delegation, Extension, 상속, 합성) (0) 2021.08.25 Protocol 1편 (Protocol 정의 방법) (0) 2021.08.16 Class의 상속 (0) 2021.08.15