Foto do ChristopherPluta no Pixabay

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.

  1. Criar uma extension de UIScrollView com o método toImage que retorna uma UIImage;
  2. Usar o UIGraphicsBeginImageContext com o contentSize;
  3. Armazenar: contentOffset, frame, showsVerticalScrollIndicator e showsVerticalScrollIndicator. Assim podemos retornar esses valores para o que eram antes;
  4. Colocar showsVerticalScrollIndicator e showsHorizontalScrollIndicator para false. Não queremos scrolls na nossa imagem;
  5. Setar contentOffset para CGPoint.zero. Queremos um frame começando sem considerar o scroll que o usuário possa ter feito;
  6. Igualamos o frame da scrollview com o seu conteúdo, assim todo o conteúdo fica "visível";
  7. Renderizamos esse o layer da scrollview no contexto atual;
  8. Transformamos o contexto atual em imagem;
  9. Resetamos os valores das propriedades modificadas para seus valores originais, e;
  10. 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. 😉👋