spiegel-keyman/ios/keyman/Keyman/SWKeyboard/ImageBannerViewController.swift

81 lines
2.5 KiB
Swift

//
// ImageBannerViewController.swift
// Keyman
//
// Created by Joshua Horton on 2/4/20.
// Copyright © 2020 SIL International. All rights reserved.
//
import Foundation
import UIKit
import KeymanEngine // for log commands
/**
* Takes in a XIB spec for an image banner and makes it renderable, applying size constraints when rendered
* to ensure proper scale. Note that the loaded UIView will never be displayed in the view hierarchy.
*/
class ImageBannerViewController: UIViewController {
// Since we never actually put this UIView into the view hierarchy, we need controlled constraints
// to control the actual frame size.
var widthConstraint: NSLayoutConstraint?
var heightConstraint: NSLayoutConstraint?
init(nibName: String, bundle: Bundle) {
super.init(nibName: nibName, bundle: bundle)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func loadView() {
super.loadView()
view.translatesAutoresizingMaskIntoConstraints = false
view.clipsToBounds = true
// Usually these would be in viewDidLoad, but they need to be redone with our manual-reload,
// and that method doesn't retrigger.
widthConstraint = view.widthAnchor.constraint(equalToConstant: 0)
widthConstraint!.isActive = true
heightConstraint = view.heightAnchor.constraint(equalToConstant: 0)
heightConstraint!.isActive = true
}
func renderToImage(size: CGSize) -> UIImage? {
if size.width == 0 || size.height == 0 {
return nil
}
let frame = CGRect(origin: self.view.frame.origin, size: size)
log.debug("Rendering banner image of size \(size)")
self.view.frame = frame
widthConstraint?.constant = size.width
heightConstraint?.constant = size.height
self.view.setNeedsLayout()
self.view.layoutIfNeeded()
// Many thanks to https://stackoverflow.com/a/4334902
var image: UIImage?
UIGraphicsBeginImageContextWithOptions(size, true, 0.0)
if let ctx = UIGraphicsGetCurrentContext() {
view.layer.render(in: ctx)
image = UIGraphicsGetImageFromCurrentImageContext()
}
UIGraphicsEndImageContext()
return image
}
public func renderAsBase64(size: CGSize) -> String? {
if let image = renderToImage(size: size), let data = image.pngData() {
// Thanks to https://stackoverflow.com/a/38748135
let base64 = data.base64EncodedString(options: [])
let url = "data:application/png;base64," + base64
return url
} else {
return nil
}
}
}