iOS 截屏&长截屏

作者: 小道萧兮 | 来源:发表于2017-08-18 22:37 被阅读600次

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

截屏

一、监听用户截屏

iOS7 开始提供一个新的监听方法:UIApplicationUserDidTakeScreenshotNotification。只要像往常一样监听系统通知即可。

// 监听屏幕截图
NotificationCenter.default.addObserver(self, selector: #selector(notify(_:)), name: NSNotification.Name.UIApplicationUserDidTakeScreenshot, object: nil)

注意:截图完成后,如果你想从通知的userInfo中获取截屏图片,那就错了,你会发现userInfo中是空的,所以需要用代码实现截屏操作,以此获取图片。

二、截屏

这里给UIView添加一个分类,这样,只要是一个UIView的子类,都可以截图了。

import UIKit

extension UIView {
    
    /// 截屏
    ///
    /// - Parameters:
    ///   - frame: 需要截取的范围,若为nil,则为视图的大小
    func screenshot(frame: CGRect? = nil) -> UIImage? {
        
        if let scrollView = self as? UIScrollView { // 如果是UIScrollView

            return scrollViewScreenShot(scrollView, frame: frame)

        } else if let webView = self as? UIWebView { // 如果是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
        }
    }
    
    /// 截取scrollView的内容
    ///
    /// - Parameters:
    ///   - scrollView: scrollView
    ///   - frame: 截取范围
    /// - Returns: 截取的图片
    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,你不点一下吗?

相关文章

  • iOS 截屏&长截屏

    截屏在 iOS 开发中经常用到,本篇文章讲的是监听用户截屏操作,并且获取截屏图片,如果当前是UIScrollVie...

  • (最新)iOS截屏

    ios webview 截屏:ios截屏 前言:介绍一下截屏有很多种做法1:截当前屏幕内容2:截整个视图的所有内容...

  • flutter:截屏

    1.flutter-截屏组件 2.flutter-截屏插件 3.flutter-iOS原生截屏 iOS代码 4.获...

  • ios截屏

    ios截屏

  • iOS 应用内截屏分享

    需求:捕获用户截屏操作,并建议用户截屏后的操作。虽然iOS11 有系统的截屏,但 APP 内截屏可便捷操作。 封装...

  • android 截屏实现

    Android 截屏分为四种:View 截屏、WebView 截屏、系统截屏 和 adb 截屏 1、View 截屏...

  • iOS 长截屏

    GitHub Demo 介绍 对 UIScrollView 及其子类 UITableView、UICollecti...

  • Android 截屏方式整理

    Android 实现截屏方式整理 可能的需求: 截自己的屏 截所有的屏 带导航栏截屏 不带导航栏截屏 截屏并编辑选...

  • 华为HarmonyOS快速上手

    1、双击截屏2、画S,滚动截长图

  • 针对WKWebView进行内容的截屏。

    最近项目中需要截屏分享的功能,之前也了解过iOS截屏的技术,并写了关于截屏的笔记,兴冲冲的拿着代码稍作修改,对WK...

网友评论

    本文标题:iOS 截屏&长截屏

    本文链接:https://www.haomeiwen.com/subject/wgjzrxtx.html