꾸르꾸르

[iOS/Swift] UIActivityViewController - 파일 공유 하는법 (share 기능) - ipad 본문

개발/Swift

[iOS/Swift] UIActivityViewController - 파일 공유 하는법 (share 기능) - ipad

GGUGGU- 2020. 5. 5. 17:32

 

안녕하세요! 지난번 포스팅에서 share panel을 만드는방법에 대해 포스팅했었는데요!

(하단포스팅참조)

http://royhelen.tistory.com/25

 

[iOS/Swift] 파일 공유 하는법 (share 기능)

다시 포스팅 시작! 오늘은 iOS에서 파일을 다른앱 또는 내 아이폰에 저장하기 등을 하기 위해 share panel을 띄우고 거기로 파일을 공유하는 방법에 대해 알아보려고 합니다. share panel이 뭔데? 라고 �

royhelen.tistory.com

 

그때 그걸로 포스팅이 끝난게 아니냐 왜 또하냐 하실텐데 지난번 포스팅대로 하면 문제가 있습니다!(?)

지난번 포스팅에서 만들었던 share panel practice를 다시 한번 열어볼까요?

작동도 되는데 뭐가 문제냐! 

저희는 폰에서만 돌려봤지 패드에서는 안돌려봤자나요?

자 그럼 이제 패드에서 실행시켜볼까요?? 그리고 share 버튼을 눌러주세요!!

share위치가 이상한데 있꾼욤..ㅎㅎㅎ;;

??

분명히 눌렀는데 왜 아무 반응이없을까요? 

화면 아무대나 클릭해봅시다.

화면 빈곳을 누르니 share cancel 이라는 토스트메시지가 뜨네요?

저희는 토스트메시지가 뜨도록 했자나요.

 

저건 share panel을 x누르거나 또는 share panel이 아닌곳을 터치해서  share panel 이 cancel되어 사라질때 나오는 메시지입니다.

그럼  share panel도 보이지 않는데 뭐가 문제일까요?

그건 바로 뜰 위치를 지정해주지 않아서 그렇습니다!

share panel의 위치가 고정되어있는 아이폰과는달리 아이패드는 share panel의 위치가 고정되어있지 않습니다!

따라서 위치를 지정해주어야겠죠.

저는 화면의 가운데에 뜨도록 해보겠습니다.

 

 

요 코드를 추가해주면 됩니다.

activityViewController.popoverPresentationController?.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.midY, width: 0, height: 0)

그리고 빌드후 실행! 

오오 뜬다..

짜잔! 이렇게 뿅! 

근데 뭔가 이상하죠..? 분명히 가운데에 했는데 가운데가 아닌거같고 뭐지..???

그건 바로 가운데에 화살표 보이시나요? 저 위치가 화면의 가운데입니다.

확대해서 보여드리면 요기!

그럼 이제 저 화살표없이 share panel만 가운데에 오도록 놓으려면 어떻게 해야할까요?

코드를 한줄더 추가합니다.

activityViewController.popoverPresentationController?.permittedArrowDirections = []

요렇게하면!

짜잔~! 제가 원하는대로 되었습니다~~

화살표가 있다면 그 화살표가 가운데, 없다면 뷰의 가운데부분이 제가 원하는 포지션에 있도록 띄어주나보군요.

또 화살표의 위치도 변경이 가능해보이는군요 (끄덕끄덕).

더 자세한 건 나중에 다른 포스팅에서 다뤄보고, 일단 오늘은 이렇게 이해하고 넘어가도록 합시다.

 

 

이제 끝~~?

아니죠.. (또 뭐가 남은거..?)

아이패드는 아이폰과는 다르게 화면회전이 가능합니다. (아이폰에서는 sharePanel이 떴을때 화면회전이 안됩니다.)

한번 돌려볼까요?

*시뮬레이터에서 화면 회전은 시뮬레이터창을 선택한채로 위에 옵션을 선택해주면됩니다.

Rotate Right 클릭!

(Orientation에서 landscape로 바꾸셔도 됩니다. Portrait가 기본세로 상태, Landscape가 가로로 돌린상태)

돌리고 나면 짜잔!

오잉???

가운데가 아니네요?

왜 그럴까요?

그건 바로 제가 가운데의 위치를 특정 position 좌표로 주었는데 화면은 돌아갔는데 그 좌표는 그대로라서 그렇습니다.

좀더 자세히 말씀드리면, 일단 Portrait상태에서 디버깅을 돌려볼까요?

즉 Portrait상태에서는 가로(x) 1024, 세로(y) 1366인 상태죠?

요기서 좌표를 x = 512, y = 683 으로 준것입니다.

이제 이걸 회전하면 Landscape모드가되면서 가로가 1366, 세로가 1024인 상태로 바뀝니다.

그러나 저희가 띄어놓은 share panel의 포지션은 여전히 그대로 x = 512, y = 683입니다.

따라서 저 위치에 놓이는 것입니다.

 

 

 

그럼 어떻게해야할까요?

화면이 돌아갈때마다 포지션을 다시 잡아주면 되겠죠.

그걸위해 viewWillTransition 함수를 이용하겠습니다.

애플문서를보니 뷰의 사이즈가 바뀔때 호출되나보군요.. (끄덕끄덕)

일단 변수 var popoverController: UIPopoverPresentationController?를 하나 만들어줍시다.

그리고 doShare함수안에 activityViewController.popoverPresentationController?.sourceRect = CGRect~~ 랑 화살표없앴던코드 있죠? 

거기를 살짝 고쳐볼게요.

if let popoverController = activityViewController.popoverPresentationController {
    self.popoverController = popoverController
    popoverController.sourceView = self.view
    popoverController.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.midY, width: 0, height: 0)
    popoverController.permittedArrowDirections = []
}

이런식으로 고쳐주겠습니다.

그리고 viewWillTransition을 만들어보겠습니다.

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
    super.viewWillTransition(to: size, with: coordinator)
    
    if let popoverController = self.popoverController {
        popoverController.sourceView = self.view
        popoverController.sourceRect = CGRect(x: size.width*0.5, y: size.height*0.5, width: 0, height: 0)
        popoverController.permittedArrowDirections = []
    }
}

변하는 사이즈의 가로와 세로의 중앙지점에다가 뷰를 그리도록 하는것입니다.

이렇게하고 빌드하면 !

portrait 모드
landscape 모드

짜잔~~ 둘다 이렇게 잘 나오게 됩니다 ㅎㅎ.

이렇게하면 패드도 끝~~! 

오늘 포스팅은 여기까지입니당.

프로젝트에 사용된 코드 전체를 보시려면 밑에 더보기를 클릭하세요.

더보기
import UIKit

class ViewController: UIViewController {
    @IBOutlet weak var shareButton: UIButton!
    var popoverController: UIPopoverPresentationController?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }
    
    override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
        super.viewWillTransition(to: size, with: coordinator)
        
        if let popoverController = self.popoverController {
            popoverController.sourceView = self.view
            popoverController.sourceRect = CGRect(x: size.width*0.5, y: size.height*0.5, width: 0, height: 0)
            popoverController.permittedArrowDirections = []
        }
    }
    
    @IBAction func doShare(_ sender: Any) {
        let shareText: String = "share text test!"
        var shareObject = [Any]()
        shareObject.append(shareText)
        let activityViewController = UIActivityViewController(activityItems : shareObject, applicationActivities: nil)
        activityViewController.popoverPresentationController?.sourceView = self.view
        activityViewController.popoverPresentationController?.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.midY, width: 0, height: 0)
        activityViewController.popoverPresentationController?.permittedArrowDirections = []

        self.present(activityViewController, animated: true, completion: nil)
        if let popoverController = activityViewController.popoverPresentationController {
            self.popoverController = popoverController
            popoverController.sourceView = self.view
            popoverController.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.midY, width: 0, height: 0)
            popoverController.permittedArrowDirections = []
        }
        
        activityViewController.completionWithItemsHandler = { (activityType: UIActivity.ActivityType?, completed: Bool, arrayReturnedItems: [Any]?, error: Error?) in
            if completed {
                self.showToast(message: "share success")
            }
            else {
                self.showToast(message: "share cancel")
            }
            if let shareError = error {
                self.showToast(message: "\(shareError.localizedDescription)")
            }
        }
    }
    
    func showToast(message : String, font: UIFont = UIFont.systemFont(ofSize: 14.0)) {
        let toastLabel = UILabel(frame: CGRect(x: self.view.frame.size.width/2 - 75, y: self.view.frame.size.height-100, width: 150, height: 35))
        toastLabel.backgroundColor = UIColor.black.withAlphaComponent(0.6)
        toastLabel.textColor = UIColor.white
        toastLabel.font = font
        toastLabel.textAlignment = .center;
        toastLabel.text = message
        toastLabel.alpha = 1.0
        toastLabel.layer.cornerRadius = 10;
        toastLabel.clipsToBounds  =  true
        self.view.addSubview(toastLabel)
        UIView.animate(withDuration: 10.0, delay: 0.1, options: .curveEaseOut, animations: {
             toastLabel.alpha = 0.0
        }, completion: {(isCompleted) in
            toastLabel.removeFromSuperview()
        })
    }
}

 

(궁금한점은 댓글 부탁드립니다!)

 

 

 

 

Comments