Screenshot de uma ScrollView no iOS (Swift)
--
O próximo desafio está sempre virando a esquina de nossas vidas e um dos desafios bacanas que tenho para passar dessa vez é fazer um print do content completo de uma scrollview.
Antes de imprimir temos que converter o conteúdo da scrollview em uma UIImage. Vejamos o passo-a-passo e o código completo.
- Criar uma extension de UIScrollView com o método toImage que retorna uma UIImage;
- Usar o UIGraphicsBeginImageContext com o contentSize;
- Armazenar: contentOffset, frame, showsVerticalScrollIndicator e showsVerticalScrollIndicator. Assim podemos retornar esses valores para o que eram antes;
- Colocar showsVerticalScrollIndicator e showsHorizontalScrollIndicator para false. Não queremos scrolls na nossa imagem;
- Setar contentOffset para CGPoint.zero. Queremos um frame começando sem considerar o scroll que o usuário possa ter feito;
- Igualamos o frame da scrollview com o seu conteúdo, assim todo o conteúdo fica "visível";
- Renderizamos esse o layer da scrollview no contexto atual;
- Transformamos o contexto atual em imagem;
- Resetamos os valores das propriedades modificadas para seus valores originais, e;
- Encerramos o contexto retornando a imagem gerada como resultado da função.
Transformando essa idéia em código propriamente dito temos:
Agora que conseguimos uma imagem do conteúdo completo da scrollview podemos chamar o UIPrintInteractionController para fazer o resto do trabalho pesado para nós.
O único import necessário aqui é o UIKit, gerei uma função onde recebemos a scrollview e uma função para quando o print falhar.
O código deve ser bem fáci de compreender, o que fazemos é criar o UIPrintInteractionController com os settings desejados e passar a imagem gerada pelo toImage para a propriedade printingItem.
func onPrintReceipt(from view: UIScrollView, onPrintFailed: @escaping () -> Void) {
let screenshot = view.toImage()
if (screenshot == nil) {
onPrintFailed()
return
}
let printController = UIPrintInteractionController.shared
let printInfo = UIPrintInfo(dictionary: [:])
printInfo.outputType = UIPrintInfoOutputType.general
printInfo.orientation = UIPrintInfoOrientation.portrait
printInfo.jobName = "Print"
printController.printInfo = printInfo
printController.showsPageRange = true
printController.printingItem = screenshot
printController.present(animated: true) { (controller, completed, error) in
if(!completed && error != nil){
onPrintFailed()
}
}
}
Com isso podemos imprimir o conteúdo de qualquer UIScrollView ou usá-lo como imagem. 😉👋