截屏在 iOS 开发中经常用到,本篇文章讲的是监听用户截屏操作,并且获取截屏图片,如果当前是UIScrollView或者UIWebView,则为获取整个scrollView的截图内容,效果图如下:

一、监听用户截屏
iOS7 开始提供一个新的监听方法:UIApplicationUserDidTakeScreenshotNotification。只要像往常一样监听系统通知即可。
1 2
   |  NotificationCenter.default.addObserver(self, selector: #selector(notify(_:)), name: NSNotification.Name.UIApplicationUserDidTakeScreenshot, object: nil)
 
  | 
 
**注意:**截图完成后,如果你想从通知的userInfo中获取截屏图片,那就错了,你会发现userInfo中是空的,所以需要用代码实现截屏操作,以此获取图片。
二、截屏
这里给UIView添加一个分类,这样,只要是一个UIView的子类,都可以截图了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
   | import UIKit
  extension UIView {                              func screenshot(frame: CGRect? = nil) -> UIImage? {                  if let scrollView = self as? UIScrollView { 
              return scrollViewScreenShot(scrollView, frame: frame)
          } else if let webView = self as? UIWebView { 
              let scrollView = webView.scrollView             return scrollViewScreenShot(scrollView, frame: frame)
          } else {             let shotFrame: CGRect = (frame == nil) ? self.bounds : frame!             UIGraphicsBeginImageContextWithOptions(shotFrame.size, true, 0)              guard let currentContext = UIGraphicsGetCurrentContext() else { return nil }
              currentContext.translateBy(x: -shotFrame.origin.x, y: -shotFrame.origin.y)             let path = UIBezierPath(rect: shotFrame)             path.addClip()             layer.render(in: currentContext)             let image = UIGraphicsGetImageFromCurrentImageContext()             UIGraphicsEndImageContext()             return image         }     }                                        private func scrollViewScreenShot(_ scrollView: UIScrollView, frame: CGRect?) -> UIImage? {                  let shotFrame: CGRect = (frame == nil) ? CGRect(origin: CGPoint(), size: scrollView.contentSize) : frame!                  UIGraphicsBeginImageContextWithOptions(shotFrame.size, false, 0)                  let savedContentOffset = scrollView.contentOffset         let savedFrame = scrollView.frame                  scrollView.contentOffset = CGPoint()         scrollView.frame = CGRect(origin: CGPoint(), size: scrollView.contentSize)                  guard let currentContext = UIGraphicsGetCurrentContext() else { return nil }                  currentContext.translateBy(x: -shotFrame.origin.x, y: -shotFrame.origin.y)                  let path = UIBezierPath(rect: shotFrame)         path.addClip()                  scrollView.layer.render(in: currentContext)                  let image = UIGraphicsGetImageFromCurrentImageContext()                  UIGraphicsEndImageContext()                  scrollView.contentOffset = savedContentOffset         scrollView.frame = savedFrame                  return image     } }
   | 
 
这是本文的Demo,你不点一下吗?