前提・実現したいこと
iOSアプリの制作を行っています。swift5,xcode12.2を使用しています。
特定のViewを画像として共有する機能を実装したいと考えています。
以下の記事を参考にさせていただいています。
https://qiita.com/tsuzuki817/items/604d059aac3e14f65942
https://qiita.com/tsuzuki817/items/a3d2470ba9df07ed0d99
初学者のため、もし不足している情報等あれば指摘していただけると幸いです。。
発生している問題・エラーメッセージ
共有ボタンを押した後、画像のように不完全なシートが表示されます。
Xcodeのエラーメッセージは以下の通りです。
[ShareSheet] connection invalidated
ただ、3回以上共有ボタンを押すと以下のように正しい表示となり、
正しく目的の画像が共有できるようになります。
該当のソースコード
共有したいViewは以下のようにしています。
swift
1struct ContentView: View { 2 3 @State private var rect: CGRect = .zero 4 @State private var uiImage: UIImage? = nil 5 // modalを表示するためのフラグを持つ 6 @State private var showShareSheet = false 7 8 9 var body: some View { 10 NavigationView { 11 VStack{ 12 TestView() 13 .edgesIgnoringSafeArea(Edge.Set.all) 14 .navigationBarItems( 15 leading: Text("") 16 }), 17 //以下で共有ボタンを表示 18 trailing: Button(action: { 19 self.uiImage = UIApplication.shared.windows[0].rootViewController?.view!.getImage(rect: self.rect) 20 self.showShareSheet.toggle() 21 }) { 22 Image(systemName: "square.and.arrow.up") 23 }.sheet(isPresented: self.$showShareSheet) { 24 25 ShareSheet(activityItems: [uiImage as Any]) 26 }.padding() 27 ) 28 .navigationBarTitle("", displayMode: .inline) 29 }.background(RectangleGetter(rect: $rect))// 30 .onAppear(){}
GeometryReader
で目的のViewのgeometryを取得したうえで、
createView
メソッドを用いてViewのサイズと位置情報をBindingしたrectに提供しています。
swift
1 2struct RectangleGetter: View { 3 @Binding var rect: CGRect 4 5 var body: some View { 6 GeometryReader { geometry in 7 self.createView(proxy: geometry) 8 } 9 } 10 //RectにViewのサイズと位置情報を提供 11 func createView(proxy: GeometryProxy) -> some View { 12 DispatchQueue.main.async { 13 self.rect = proxy.frame(in: .global) 14 } 15 return Rectangle().fill(Color.clear) 16 } 17}
UIViewからUIImageへの変換は以下のようにUIGraphicsImageRenderer
を
利用しています。
swift
1extension UIView { 2 func getImage(rect: CGRect) -> UIImage { 3 let renderer = UIGraphicsImageRenderer(bounds: rect) 4 return renderer.image { 5 rendererContext in layer.render(in: rendererContext.cgContext) 6 } 7 } 8}
試したこと
Simulatorと実機両方でテストを行いましたが同じ結果でした。(iOS14)
あなたの回答
tips
プレビュー