source

Swift의 UIActivityViewController로 텍스트 또는 이미지를 공유하기 위한 기본 예제

factcode 2023. 4. 29. 09:55
반응형

Swift의 UIActivityViewController로 텍스트 또는 이미지를 공유하기 위한 기본 예제

iOS에서 다른 앱과 공유할 수 있는 방법을 알고 싶어서 검색을 시작했습니다.나는 두 가지 중요한 방법이 있다는 것을 발견했습니다.

  • UIActivityViewController
  • UIDocumentInteractionController

SO 답변에서는 이러한 방법과 다른 방법을 비교합니다.

종종 새로운 개념을 배울 때, 저는 저를 시작할 수 있는 기본적인 예를 보는 것을 좋아합니다.기본 설정을 받으면 나중에 원하는 대로 수정할 수 있습니다.

다음과 관련된 SO 질문이 많습니다.UIActivityViewController단순한 예를 들어달라는 말은 하나도 찾을 수가 없었어요.제가 이제 막 이 방법을 배웠기 때문에, 저는 아래에 저만의 답을 제공하겠습니다.더 나은 버전(또는 Objective-C 버전)을 자유롭게 추가할 수 있습니다.

UIActivityView 컨트롤러 예제 프로젝트

두 개의 버튼으로 스토리보드를 설정하고 보기 컨트롤러에 연결합니다(아래 코드 참조).

여기에 이미지 설명 입력

이미지를 Assets.xcassets에 추가합니다.저는 제 것을 "사자"라고 불렀습니다.

여기에 이미지 설명 입력

코드

import UIKit
class ViewController: UIViewController {
    
    // share text
    @IBAction func shareTextButton(_ sender: UIButton) {
        
        // text to share
        let text = "This is some text that I want to share."
        
        // set up activity view controller
        let textToShare = [ text ]
        let activityViewController = UIActivityViewController(activityItems: textToShare, applicationActivities: nil)
        activityViewController.popoverPresentationController?.sourceView = self.view // so that iPads won't crash
        
        // exclude some activity types from the list (optional)
        activityViewController.excludedActivityTypes = [ UIActivity.ActivityType.airDrop, UIActivity.ActivityType.postToFacebook ]
        
        // present the view controller
        self.present(activityViewController, animated: true, completion: nil)
        
    }
    
    // share image
    @IBAction func shareImageButton(_ sender: UIButton) {
        
        // image to share
        let image = UIImage(named: "Image")
        
        // set up activity view controller
        let imageToShare = [ image! ]
        let activityViewController = UIActivityViewController(activityItems: imageToShare, applicationActivities: nil)
        activityViewController.popoverPresentationController?.sourceView = self.view // so that iPads won't crash
        
        // exclude some activity types from the list (optional)
        activityViewController.excludedActivityTypes = [ UIActivity.ActivityType.airDrop, UIActivity.ActivityType.postToFacebook ]
        
        // present the view controller
        self.present(activityViewController, animated: true, completion: nil)
    }
    
}

결과

일부 텍스트 공유를 클릭하면 왼쪽에 결과가 표시되고 이미지 공유를 클릭하면 오른쪽에 결과가 표시됩니다.

여기에 이미지 설명 입력

메모들

  • 저는 iOS 11과 Swift 4로 이것을 다시 테스트했습니다.시간이 초과되어 작동하기 전에 시뮬레이터에서 몇 번 실행해야 했습니다.이것은 아마도 내 컴퓨터가 느려서일 것입니다.
  • 이러한 선택사항 중 일부를 숨기려면 다음을 사용하여 수행할 수 있습니다.excludedActivityTypes위의 코드에 나타난 바와 같이.
  • 포함하지 않음popoverPresentationController?.sourceViewline은 iPad에서 실행될 때 당신의 앱이 충돌하게 할 것입니다.
  • 이렇게 하면 텍스트 또는 이미지를 다른 앱과 공유할 수 없습니다.당신은 아마 원할 것입니다.UIDocumentInteractionController그것 때문에

참고 항목

공유: 텍스트

@IBAction func shareOnlyText(_ sender: UIButton) {
    let text = "This is the text....."
    let textShare = [ text ]
    let activityViewController = UIActivityViewController(activityItems: textShare , applicationActivities: nil)
    activityViewController.popoverPresentationController?.sourceView = self.view 
    self.present(activityViewController, animated: true, completion: nil)
}
}

공유: 이미지

@IBAction func shareOnlyImage(_ sender: UIButton) {
    let image = UIImage(named: "Product")
    let imageShare = [ image! ]
    let activityViewController = UIActivityViewController(activityItems: imageShare , applicationActivities: nil)
    activityViewController.popoverPresentationController?.sourceView = self.view 
    self.present(activityViewController, animated: true, completion: nil)
 }

공유 : 텍스트 - 이미지 - URL

   @IBAction func shareAll(_ sender: UIButton) {
    let text = "This is the text...."
    let image = UIImage(named: "Product")
    let myWebsite = NSURL(string:"https://stackoverflow.com/users/4600136/mr-javed-multani?tab=profile")
    let shareAll= [text , image! , myWebsite]
    let activityViewController = UIActivityViewController(activityItems: shareAll, applicationActivities: nil)
    activityViewController.popoverPresentationController?.sourceView = self.view 
    self.present(activityViewController, animated: true, completion: nil)
   }

여기에 이미지 설명 입력

참고로 iPad에서도 이 기능을 사용할 수 있습니다.

activityViewController.popoverPresentationController?.sourceView = sender

따라서 발신자(이 경우 버튼)로부터 팝업이 표시됩니다.

화면 전체를 공유하고 싶다면 완벽하게 작동합니다.

@IBAction func shareButton(_ sender: Any) {

    let bounds = UIScreen.main.bounds
    UIGraphicsBeginImageContextWithOptions(bounds.size, true, 0.0)
    self.view.drawHierarchy(in: bounds, afterScreenUpdates: false)
    let img = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    let activityViewController = UIActivityViewController(activityItems: [img!], applicationActivities: nil)
    activityViewController.popoverPresentationController?.sourceView = self.view
    self.present(activityViewController, animated: true, completion: nil)
}

위의 구현을 사용했는데 iOS 13을 실행하는 iPad에서는 작동하지 않는다는 것을 방금 알게 되었습니다.통화 전에 이 대사를 추가해야 했습니다. 통화하기 전에 이 대사들을 추가해야 했습니다.

//avoiding to crash on iPad
if let popoverController = activityViewController.popoverPresentationController {
     popoverController.sourceRect = CGRect(x: UIScreen.main.bounds.width / 2, y: UIScreen.main.bounds.height / 2, width: 0, height: 0)
     popoverController.sourceView = self.view
     popoverController.permittedArrowDirections = UIPopoverArrowDirection(rawValue: 0)
}

그게 내게 맞는 방식입니다.

func shareData(_ dataToShare: [Any]){

        let activityViewController = UIActivityViewController(activityItems: dataToShare, applicationActivities: nil)

        //exclude some activity types from the list (optional)
        //activityViewController.excludedActivityTypes = [
            //UIActivity.ActivityType.postToFacebook
        //]

        //avoiding to crash on iPad
        if let popoverController = activityViewController.popoverPresentationController {
            popoverController.sourceRect = CGRect(x: UIScreen.main.bounds.width / 2, y: UIScreen.main.bounds.height / 2, width: 0, height: 0)
            popoverController.sourceView = self.view
            popoverController.permittedArrowDirections = UIPopoverArrowDirection(rawValue: 0)
        }

        self.present(activityViewController, animated: true, completion: nil)
    }

당신은 제가 프로젝트의 도우미 수업에서 작성한 다음 기능을 사용할 수 있습니다.

그냥 전화하세요.

showShareActivity(msg:"message", image: nil, url: nil, sourceRect: nil) 

iPhone과 iPad 모두에 사용할 수 있습니다.보기의 CGRect 값을 sourceRect로 전달하면 iPad에도 작은 화살표가 표시됩니다.

func topViewController()-> UIViewController{
    var topViewController:UIViewController = UIApplication.shared.keyWindow!.rootViewController!

    while ((topViewController.presentedViewController) != nil) {
        topViewController = topViewController.presentedViewController!;
    }

    return topViewController
}

func showShareActivity(msg:String?, image:UIImage?, url:String?, sourceRect:CGRect?){
    var objectsToShare = [AnyObject]()

    if let url = url {
        objectsToShare = [url as AnyObject]
    }

    if let image = image {
        objectsToShare = [image as AnyObject]
    }

    if let msg = msg {
        objectsToShare = [msg as AnyObject]
    }

    let activityVC = UIActivityViewController(activityItems: objectsToShare, applicationActivities: nil)
    activityVC.modalPresentationStyle = .popover
    activityVC.popoverPresentationController?.sourceView = topViewController().view
    if let sourceRect = sourceRect {
        activityVC.popoverPresentationController?.sourceRect = sourceRect
    }

    topViewController().present(activityVC, animated: true, completion: nil)
}

iOS 텍스트 또는 이미지 공유

UIActivityViewController

let controller = UIActivityViewController(activityItems: [someObject], applicationActivities: nil) //someObject can be UIImage, NSURL, String... iOS decide how to handle it properly
controller.popoverPresentationController?.sourceView = self.view

controller.completionWithItemsHandler = {
    (
        activityType: UIActivity.ActivityType?,
        completed: Bool,
        arrayReturnedItems: [Any]?,
        error: Error?
    ) in
    
    if let error = error {
        //error occured
        return
    }
    
    if completed {
        if let activityType = activityType {
            switch activityType {
            case .saveToCameraRoll:
                break
            case .copyToPasteboard:
                break
            case .addToReadingList:
                break
            case .airDrop:
                break
            default:
                //all others
                break
            }
        }
    } else {
        //Cancel
    }
}

self.present(controller, animated: true)

하려면 이미를라에저장경우추할가리러이브지추▁add▁if가▁into경우▁image이를 추가합니다.NSPhotoLibraryAddUsageDescription앱로에.plist하지 않으면 오류가 발생합니다.

This app has crashed because it attempted to access privacy-sensitive data without a usage description. The app's Info.plist must contain an NSPhotoLibraryAddUsageDescription key with a string value explaining to the user how the app uses this data.

또는 이 기회를 제외하십시오.

controller.excludedActivityTypes = [.saveToCameraRoll]

이 붙은 completionWithItemsHandler포스트 로직을 추가하거나 오류를 처리하는 데 도움이 될 수 있습니다.

예를 들어 UI 이미지를 해당 핸들러의 사진 라이브러리에 저장할 때 다음 오류가 발생합니다.

Error Domain=ALAssetsLibraryErrorDomain Code=-1 "Unknown error" UserInfo={NSLocalizedDescription=Unknown error, NSUnderlyingError=0x600003f85110 {Error Domain=PHPhotosErrorDomain Code=3303 "(null)"}}

내가 구하려고 했던 것처럼CIImage변형으로 변환할 수 있습니다.CGImage

let context = CIContext()
guard let cgImage = context.createCGImage(output, from: output.extent) else { return nil }
return UIImage(cgImage: cgImage)

언급URL : https://stackoverflow.com/questions/35931946/basic-example-for-sharing-text-or-image-with-uiactivityviewcontroller-in-swift

반응형