簡體   English   中英

以編程方式在 swift 上截圖

[英]Screenshot on swift programmatically

當我按下 swift 中的一個按鈕時,我試圖截取整個視圖的屏幕截圖。問題是,當我截取屏幕截圖時,某些部分被切斷了,比如頂部......

在此處輸入圖像描述

被切斷的其他部分是我在屏幕底部的容器視圖。 它包含一個開關、一個文本字段和一個按鈕。 這是我用來截屏的代碼......

func screenShotMethod() {
    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()

    UIImageWriteToSavedPhotosAlbum(screenshot!, nil, nil, nil)
}

這是我用來創建容器視圖的代碼...

lazy var inputContainerView: UIView = {

    let containerView = UIView()
    containerView.frame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: 50)
    containerView.backgroundColor = UIColor.white
    //Other things...

override var inputAccessoryView: UIView? {
    get {
        return inputContainerView
    }
}

override var canBecomeFirstResponder : Bool {
    return true
}

這就是結局圖像的樣子...... 在此處輸入圖像描述

那我該怎么做才能解決呢? 謝謝!

如果您具有某種Objective-C知識,那么這里就是您想要的答案。

打開此鏈接,並遵循在所有視圖層次結構中進行迭代的最后一個答案,並逐行注釋以完全理解代碼。

圖像最終被轉換為NSDataUIImage 如果您仍然感到困惑,那么我可以將其轉換為快捷方式,但請先自行嘗試。

這是該答案的Swift代碼。

func screenshot() -> UIImage {
    let imageSize = UIScreen.main.bounds.size as CGSize;
    UIGraphicsBeginImageContextWithOptions(imageSize, false, 0)
    let context = UIGraphicsGetCurrentContext()
    for obj : AnyObject in UIApplication.shared.windows {
        if let window = obj as? UIWindow {
            if window.responds(to: #selector(getter: UIWindow.screen)) || window.screen == UIScreen.main {
                                // so we must first apply the layer's geometry to the graphics context
                                context!.saveGState();
                                // Center the context around the window's anchor point
                                context!.translateBy(x: window.center.x, y: window.center
                                    .y);
                                // Apply the window's transform about the anchor point
                                context!.concatenate(window.transform);
                                // Offset by the portion of the bounds left of and above the anchor point
                context!.translateBy(x: -window.bounds.size.width * window.layer.anchorPoint.x,
                                     y: -window.bounds.size.height * window.layer.anchorPoint.y);

                                // Render the layer hierarchy to the current context
                                window.layer.render(in: context!)

                                // Restore the context
                                context!.restoreGState();
            }
        }
    }
    let image = UIGraphicsGetImageFromCurrentImageContext();
    return image!
}

在 Swift 5.0 中,它可能是:

yourView.snapshot(saveToHDR: false) { image in
        UIImageWriteToSavedPhotosAlbum(image!, nil, nil, nil)
    }

我將其用於 AR 功能,無需屏幕上的所有按鈕即可進行拍攝。

您可以將此警告結合起來做不同的事情,例如保存或共享:

在按鈕內:

        yourView.snapshot(saveToHDR: false) { image in
        if let saveImage = image {
            self.saveAndExport(sender: sender, saveImage: saveImage)
        }
    }

保存並導出警報:

func saveAndExport(sender: UIButton, saveImage: UIImage){
    let image: UIImage = saveImage
    var exportName:String?
    
    var alert = UIAlertController(title: "Title"  , message: "Subtitle", preferredStyle: .actionSheet)
    
    
    // Setup for Ipad preferredStyle: .alert cause it cant show preferredStyle: .actionSheet)
    if UIDevice.current.userInterfaceIdiom == .pad {
    alert = UIAlertController(title: "Title", message: "Subtitle", preferredStyle: .alert)
    }
    
    let shareFunctions = UIAlertAction(title: "Share", style: .default) { (action) in
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "yyyyMMddhhmmss"
        exportName = dateFormatter.string(from: Date()).appending(".jpg")
        //            }
        let documentsPathUSDZ = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
        let urlUSDZ = documentsPathUSDZ.appendingPathComponent("\(exportName!).jpeg")
        do {
            try image.jpegData(compressionQuality: 1.0)?.write(to: urlUSDZ, options: .atomic)
            let activityController = UIActivityViewController(activityItems: [urlUSDZ], applicationActivities: nil)
            activityController.popoverPresentationController?.sourceView = sender
            self.present(activityController, animated: true, completion: nil)
        } catch let error {
            fatalError(error.localizedDescription)
        }
    }
    
    let backAction = UIAlertAction(title: "Back", style: .default) { (action) in
    }
    
    let saveInPhotos = UIAlertAction(title: "Save", style: .default) { (action) in
        UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil)
    }
    

    let saveImage = UIImage.init(systemName: "square.and.arrow.down")
    saveInPhotos.setValue(saveImage, forKey: "image")
    saveInPhotos.setValue(CATextLayerAlignmentMode.left, forKey: "titleTextAlignment")
    
    let shareImage = UIImage.init(systemName: "square.and.arrow.up")
    shareFunctions.setValue(shareImage, forKey: "image")
    shareFunctions.setValue(CATextLayerAlignmentMode.left, forKey: "titleTextAlignment")
    
    let backImage = UIImage.init(systemName: "chevron.backward")
    backAction.setValue(backImage, forKey: "image")
    backAction.setValue(CATextLayerAlignmentMode.left, forKey: "titleTextAlignment")
    
    
    alert.addAction(saveInPhotos)
    alert.addAction(shareFunctions)
    alert.addAction(backAction)
    present(alert, animated: true, completion: nil)
}

但這在 iPad 上不起作用,我找不到解決方法。 即使我將 preferredStyle 更改為:.alert

如果有人知道為什么請幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM