Сделай скриншот с фоновым изображением - iOS - PullRequest
1 голос
/ 06 марта 2019

Я хочу сделать скриншот.На этом скриншоте я хочу текст и изображение в нем.Однако у меня возникла проблема, потому что, когда я делаю снимок экрана, я вижу только текст, но не изображение.

Мне кажется, проблема в том, что clearContainerView содержит только текст, но не изображение.Я не могу поместить изображение внутри clearContainerView, потому что я хочу, чтобы изображение растягивалось на весь экран ... и я хочу, чтобы текст располагался по центру между заголовком и панелью вкладок (как показано зеленым квадратом выше).

Мой код и картинки ниже:

Это мой текущий макет в раскадровке: enter image description here

Вот чтоМне нужен скриншот: enter image description here

Это скриншот, который я получаю: enter image description here

Это мой код:

@IBOutlet weak var clearContainerView: UIView!

@IBAction func takeScreenshotTapped(_ sender: UIButton) {
    let screenshot = clearContainerView.screenshot()
    print(screenshot)
}

extension UIView {
    func screenshot() -> UIImage {
        let image = UIGraphicsImageRenderer(size: bounds.size).image { _ in
            drawHierarchy(in: CGRect(origin: .zero, size: bounds.size), afterScreenUpdates: true)
        }

        return image
    }
}

Есть предложения о том, как это сделать?

Ответы [ 6 ]

1 голос
/ 06 марта 2019

Вы можете использовать следующий метод в вашем представлении контроллера, чтобы получить часть clearContainerView, которая будет представлением снимка.Затем вы можете использовать этот объект просмотра и сделать его снимок экрана.

resizableSnapshotViewFromRect:afterScreenUpdates:withCapInsets:

Вы должны передать прямоугольник, который будет вашим кадром clearContainerView.Вы можете пропустить нулевые вставки, если вам не нужен растягиваемый контент.Он возвращает объект представления, который будет содержать вашу часть imageView + ваш полный clearContainerView.Затем вы можете использовать возвращенный вид и сделать его снимок экрана.

Я попытался со следующим.

Мой исходный вид.

enter image description here

Скриншот

enter image description here

0 голосов
/ 06 марта 2019

Используйте это расширение.

//USAGE



 let image = self.view.snapshot(of:self.<your view>.frame) 

Здесь «ваше представление» должно быть базовым представлением из иерархии, или вы можете просто использовать

 let image = self.view.snapshot(of:self.view.frame)

Расширение

// UIView screenshot
extension UIView {

    /// Create snapshot
    ///
    /// - parameter rect: The `CGRect` of the portion of the view to return. If `nil` (or omitted),
    ///                   return snapshot of the whole view.
    ///
    /// - returns: Returns `UIImage` of the specified portion of the view.

    func snapshot(of rect: CGRect? = nil) -> UIImage? {
        // snapshot entire view

        UIGraphicsBeginImageContextWithOptions(bounds.size,  false, 0.0)
        drawHierarchy(in: bounds, afterScreenUpdates: true)
        let wholeImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        // if no `rect` provided, return image of whole view

        guard let image = wholeImage, let rect = rect else { return wholeImage }

        // otherwise, grab specified `rect` of image

        let scale = image.scale
        let scaledRect = CGRect(x: rect.origin.x * scale, y: rect.origin.y * scale, width: rect.size.width * scale, height: rect.size.height * scale)
        guard let cgImage = image.cgImage?.cropping(to: scaledRect) else { return nil }
        return UIImage(cgImage: cgImage, scale: scale, orientation: .up)
    }

}
0 голосов
/ 06 марта 2019

Попробуй это! Вспомогательная функция

struct UIGraphicsDrawImageHelper {
    static func drawImage(from image: UIImageView) -> UIImage? {
        UIGraphicsBeginImageContextWithOptions(image.bounds.size, image.isOpaque, 0.0)
        image.drawHierarchy(in: image.bounds, afterScreenUpdates: false)
        let renderImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return renderImage
    }
}

называя это

guard let image = UIGraphicsDrawImageHelper.drawImage(from: qrcodeImageView) else { return }

ImageView (Clear Container View) - это представление, которое вы хотите сделать снимок экрана. Вы можете изменить его на uiview или любой другой вид Надеюсь, что это поможет.

0 голосов
/ 06 марта 2019

Все хорошо. Я сделал демо для вашего ожидаемого результата.

Вам просто нужно изменить иерархию представления следующим образом:

Как пр вы говорите изображение, если за пределами clearContainerView

enter image description here

Код

class VC: UIViewController {

    @IBOutlet weak var mainVw: UIView!
    @IBOutlet weak var clearContainerView: UIView!

    override func viewDidLoad() {
        super.viewDidLoad()
    }


    @IBAction func takeImage(_ sender: Any) {

        if let VC_1 = self.storyboard?.instantiateViewController(withIdentifier: "VC1") as? VC1{
            VC_1.img = mainVw.screenshot()
            self.present(VC_1, animated: false, completion: nil)
        }
    }
}

Выход:

enter image description here

0 голосов
/ 06 марта 2019

Вы можете использовать код, указанный ниже, чтобы сделать снимок экрана.Это захватит все окно, а не конкретный вид.Но позаботьтесь об одном: если вы не хотите, чтобы ваши «Заголовок», «Кнопка» и «Панель вкладок» на скриншоте, вам нужно скрыть их до UIGraphicsBeginImageContextWithOptions и показать их снова после UIGraphicsEndImageContext.

func takeScreenshot() -> UIImage? {
        var screenshotImage: UIImage?
        let layer = UIApplication.shared.keyWindow!.layer
        let scale = UIScreen.main.scale
        // Hide your title label, button and tab bar here
        UIGraphicsBeginImageContextWithOptions(layer.frame.size, false, scale);
        guard let context = UIGraphicsGetCurrentContext() else {return nil}
        layer.render(in:context)
        screenshotImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        // Unhide your title label, button and tab bar here
        return screenshotImage
}

@IBAction func takeScreenshotTapped(_ sender: UIButton) {
    let screenshot = takeScreenshot()
    print(screenshot)
}
0 голосов
/ 06 марта 2019

Основной код:

let frame = containerView.frame
let x: CGFloat = 0
let y = frame.minY.pointsToPixel()
let width = frame.width.pointsToPixel()
let height = frame.height.pointsToPixel()
let rect = CGRect(x: x, y: y, width: width, height: height)
let image = cropImage(image: view.screenshot(), toRect: rect)


extension UIView {
    func screenshot() -> UIImage {
        let image = UIGraphicsImageRenderer(size: bounds.size).image { _ in
            drawHierarchy(in: CGRect(origin: .zero, size: bounds.size), afterScreenUpdates: true)
        }

        return image
    }
}
public extension CGFloat {
    func pointsToPixel() -> CGFloat {
        return self * UIScreen.main.scale
    }

}

Выход: enter image description here

После скриншота: enter image description here

Что я сделал: сделайте скриншот всего вида с помощью вашего метода, а затем обрежьте изображение, преобразовав CGPoints в пиксели.

...