I have a screenshot of the entire screen, screenshot
, generated using the following:
let layer = UIApplication.sharedApplication().keyWindow!.l
My answer in Swift 4.2, the steps are in the comments above the code in the function getScreenshot()
@IBAction fileprivate func takeScreenshotButtonTapped(_ sender: UIButton) {
guard let croppedScreenshotImage = getScreenshot() else { return }
// do something with the croppedScreenshotImage
}
func getScreenshot() -> UIImage? {
// 1. get screenshot of the entire screen
UIGraphicsBeginImageContext(UIApplication.shared.keyWindow!.bounds.size)
UIApplication.shared.keyWindow!.layer.render(in: UIGraphicsGetCurrentContext()!)
let screenshot = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
// 2. height of statusBar
let statusBarHeight = UIApplication.shared.statusBarFrame.size.height
// 3. height of navigationBar
var navBarHeight: CGFloat = 0
if let navigationBarHeight = navigationController?.navigationBar.frame.height {
navBarHeight = navigationBarHeight
}
// 4. total height of statusBar + navigationBar
let topBarHeight = statusBarHeight + navBarHeight
// 5. get the height of the tabBar
var tabBarHeight: CGFloat = 0
if let tabBarController = tabBarController {
tabBarHeight = tabBarController.tabBar.frame.size.height
}
// 6. to exclude the navigationBar, statusBar, and tabBar from your screenshot start the rect's y-axis at everything below the topBarHeight. For the height subtract the topBarHeight and tabBarHeight from the view's height
let rectWithoutNavStatusAndTabBar = CGRect(x: 0, y: topBarHeight, width: self.view.bounds.width, height: self.view.bounds.height - topBarHeight - tabBarHeight)
guard let safeScreenshot = screenshot else { return nil }
// 7. crop the screenshot to the rectWithoutNavStatusAndTabBar
guard let cgImage = safeScreenshot.cgImage?.cropping(to: rectWithoutNavStatusAndTabBar) else { return nil }
// 8. create an image from the cgImage
let yourCroppedScreenshotImage = UIImage(cgImage: cgImage)
return yourCroppedScreenshotImage
}
This is also the Swift 4.2 version of the accepted answer:
func takeScreenshot(sender: AnyObject) {
let layer = UIApplication.shared.keyWindow!.layer
let scale = UIScreen.main.scale
UIGraphicsBeginImageContextWithOptions(layer.frame.size, false, scale);
layer.render(in: UIGraphicsGetCurrentContext()!)
let screenshot = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
let croppedImage = self.cropImage(screenshot: screenshot!)
}
func cropImage(screenshot: UIImage) -> UIImage {
let scale = screenshot.scale
let imgSize = screenshot.size
let screenHeight = UIScreen.main.bounds.height
let bound = self.view.bounds.height
let navHeight = self.navigationController!.navigationBar.frame.height
let bottomBarHeight = screenHeight - navHeight - bound
let crop = CGRect(x: 0, y: 0, width: (imgSize.width - 1) * scale, height: (imgSize.height - bottomBarHeight - 1) * scale)
let cgImage = screenshot.cgImage?.cropping(to: crop)
let image: UIImage = UIImage(cgImage: cgImage!)
return image
}