使用iOS手机的同学,在平时操作APP的时候肯定会遇到这种情况,当你在试用期间截图时,APP会自动弹出你的截图,并且提示你分享或者反馈。这种效果看起来很牛逼,但实际上是一个十分容易实现的需求,因为在iOS7以后苹果为大家提供了一个获取截图的通知,会在截图后调用:
OC:UIApplicationUserDidTakeScreenshotNotification
Swift:UIApplicationUserDidTakeScreenshot
获取到截图的通知有什么用呢?有些同学会想,是不是此时调用系统的相册,获取相册的最后一张图片。这个方法可以,只不过太笨了,你还要写一堆调用系统相册的方法,写到最后会让你感到淡淡的悲伤。其实最简单和高效的方法,就是在接收到通知的同时,直接截取手机屏幕内的图片。高效又方便,不用调用一大堆系统方法,接下来,我就给大家将Swift的代码上一下。
import UIKit
class ViewController: UIViewController {
//随便加的一个imageView
@IBOutlet weak var imageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
///添加通知
NotificationCenter.default.addObserver(self, selector: #selector(ViewController.userDidTakeScreenshot), name: NSNotification.Name.UIApplicationUserDidTakeScreenshot, object: nil)
}
deinit {
///移除通知
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIApplicationUserDidTakeScreenshot, object: nil)
}
//截屏通知
@objc func userDidTakeScreenshot() {
//获取屏幕图片
let image = takeScreenshot()
imageView.image = image
}
/// 截取当前屏幕
func takeScreenshot() -> UIImage {
var imageSize = CGSize.zero
let screenSize = UIScreen.main.bounds.size
let orientation = UIApplication.shared.statusBarOrientation
if UIInterfaceOrientationIsPortrait(orientation) {
imageSize = screenSize
} else {
imageSize = CGSize(width: screenSize.height, height: screenSize.width)
}
UIGraphicsBeginImageContextWithOptions(imageSize, false, 0)
if let context = UIGraphicsGetCurrentContext() {
for window in UIApplication.shared.windows {
context.saveGState()
context.translateBy(x: window.center.x, y: window.center.y)
context.concatenate(window.transform)
context.translateBy(x: -window.bounds.size.width * window.layer.anchorPoint.x, y: -window.bounds.size.height * window.layer.anchorPoint.y)
if orientation == UIInterfaceOrientation.landscapeLeft {
context.rotate(by: .pi / 2)
context.translateBy(x: 0, y: -imageSize.width)
} else if orientation == UIInterfaceOrientation.landscapeRight {
context.rotate(by: -.pi / 2)
context.translateBy(x: -imageSize.height, y: 0)
} else if orientation == UIInterfaceOrientation.portraitUpsideDown {
context.rotate(by: .pi)
context.translateBy(x: -imageSize.width, y: -imageSize.height)
}
if window.responds(to: #selector(UIView.drawHierarchy(in:afterScreenUpdates:))) {
window.drawHierarchy(in: window.bounds, afterScreenUpdates: true)
} else {
window.layer.render(in: context)
}
context.restoreGState()
}
}
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
if let image = image {
return image
} else {
return UIImage()
}
}
}
其实很简单的朋友们,不过最后还有一点点小小的建议。如果你想在APP内全局都实现这个功能,我建议你将这个通知放在BaseController的viewDidLoad中,大家只要记得在控制器销毁时移除通知就行了。这样在全局都可以实现截图分享、截图反馈等功能。ok,喜欢的话可以点一波收藏。