快速说明

  • 介绍:SwiftUI 中,支撑自定义截图的 View
  • 库房地址:RickeyBoy/ScreenshotableView
  • 我的其他文章合集:RickeyBoy – Github

事例演示

本篇讲讲实战运用,下篇再讲一下完成原理

在 app 开发过程中,咱们常常需求用到截图的功用,比如一个典型场景就是做【共享/保存图片】功用。

如下图所示,咱们想要依靠已有的 UI,快速生成一个共享图,用 RickeyBoy/ScreenshotableView 就能快速完成了。

SwiftUI 如何实现自定义截图

完成步骤

1. 引进组件

运用 Swift Package Manager 引进工程即可,十分方便

经过 Xcode File > Swift Packages > Add Pacage Dependency...,再输入 https://github.com/RickeyBoy/ScreenshotableView 搜索增加

SwiftUI 如何实现自定义截图

2. 增加截图按钮

首要,咱们假定咱们现已完成了一个页面的款式(基于 SwiftUI 是十分容易画 UI 的)。咱们将中间的部分看做一个全体,命名为 CustomView:

SwiftUI 如何实现自定义截图

那么这儿的页面布局就十分简略了:

varbody:someView{
    VStack{
     ...// Headers
     
     CustomView()
     
     ...// Tab buttons
    }
}

不同于 Objective C 和 Swift 中手动增加 Action 的方法,SwiftUI 需求经过 @State 关键字的变量,来绑定截图状态。所以咱们在引进 ScreenshotableView 后,需求增加符号位,来完成截图的功用。

在想要截图时,直接调用 shotting.toggle() 就行了。

varbody:someView{
     @Statevarshotting=false
     VStack{
       ...// Headers
       ScreenshotableView(shotting:$shotting){screenshotin
           // 回来 screenshot 截图
       }content:{
           // 原有的 CustomView 内容
           CustomView()
       }
       ...// Tab buttons
     }
     funcscreenshot(){
       // 触发截图
       shotting.toggle()
     }
}

此时,假如直接输出截图的图片结果 screenshot,就会直接得到一张和 CustomView 一模一样的图片:

SwiftUI 如何实现自定义截图

3. 完成自定义款式

怎么完成展现作用 vs 截图作用的不同?ScreenshotView 其实供给了十分便捷的完成方法,在 block 中可以直接捕获到 style,包括 inViewinScreenshot 两个枚举类型,分别代表展现作用、截图作用。咱们将参数透传给 Custom 即可:

varbody:someView{
    @viewBuilder
    funcCustomView(style:ScreenshotableViewStyle)->someView{
        ifstyle==.inView{
             // 展现时运用白色布景
            content
               .background(.white)
        }else{
             // 截图时运用自定义的渐变色布景
             content
               .background{LinearGradient(...)}
        }
    }
}

SwiftUI 如何实现自定义截图

4. 给截图增加底部额外信息

经过截图组件,咱们能够拿到截图后回调的图片。那么就可以直接做一个简略的拼接,就可以得到终究的结果图了:

extensionUIImage{
 /// 拼接共享底部 banner
 funcaddShareBanner()->UIImage{
   // 资源图片
   letqrCodeImage=UIImage(named:"AppQRCode")!
   letlogoImage=UIImage(named:"Logo")!
   // 参数
   letbannerHeight:CGFloat=92/// 新增 banner 的高度
   letnewImageSize=CGSize(width:self.size.width,height:self.size.height+bannerHeight)
   // 新增画布
   UIGraphicsBeginImageContextWithOptions(newImageSize,false,UIScreen.main.scale)
   // 绘制本来的 Image
   self.draw(at:CGPoint.zero)
   // 绘制二维
   letqrCodeRect=CGRect(origin:CGPoint(x:24,y:self.size.height+10),size:CGSize(width:72,height:72))
   qrCodeImage.draw(in:qrCodeRect)
   // 绘制 Logo
   letlogoSize=CGSize(width:74,height:30)
   letlogoRect=CGRect(origin:CGPoint(x:newImageSize.width-12-logoSize.width,y:newImageSize.height-12-logoSize.height),size:logoSize)
   logoImage.draw(in:logoRect)
   // 生成
   letimage=UIGraphicsGetImageFromCurrentImageContext()
   UIGraphicsEndImageContext()
   returnimage??self
 }
}

咱们只需求在回调中进行处理,就能得到咱们终究的共享图了:

varbody:someView{
 @Statevarshotting=false
 VStack{
   ...// Headers
   ScreenshotableView(shotting:$shotting){screenshotin
     // 回来 screenshot 截图
     sharedImage=screenshot.addShareComponent()
   }content:{stylein
     // 原有的 CustomView 内容
     CustomView(style:style)
   }
   ...// Tab buttons
 }
 funcscreenshot(){
   // 触发截图
   shotting.toggle()
 }
}

SwiftUI 如何实现自定义截图