Swift: Cropping a Screenshot without TabBar and NavigationBar

前端 未结 5 824
臣服心动
臣服心动 2021-01-05 14:43

I have a screenshot of the entire screen, screenshot, generated using the following:

let layer = UIApplication.sharedApplication().keyWindow!.l         


        
5条回答
  •  不思量自难忘°
    2021-01-05 15:05

    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
    }
    

提交回复
热议问题