• convert ObjC code from UIView+SignalUI to Swift. • separate code from UIView+SignalUI to smaller files by functionality.
107 lines
3.4 KiB
Swift
107 lines
3.4 KiB
Swift
//
|
|
// Copyright 2023 Signal Messenger, LLC
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
//
|
|
|
|
import SignalCoreKit
|
|
|
|
public extension UIImageView {
|
|
|
|
func setImage(imageName: String) {
|
|
guard let image = UIImage(named: imageName) else {
|
|
owsFailDebug("Couldn't load image: \(imageName)")
|
|
return
|
|
}
|
|
self.image = image
|
|
}
|
|
|
|
func setTemplateImage(_ templateImage: UIImage?, tintColor: UIColor) {
|
|
guard let templateImage else {
|
|
owsFailDebug("Missing image")
|
|
return
|
|
}
|
|
self.image = templateImage.withRenderingMode(.alwaysTemplate)
|
|
self.tintColor = tintColor
|
|
}
|
|
|
|
func setTemplateImageName(_ imageName: String, tintColor: UIColor) {
|
|
guard let image = UIImage(named: imageName) else {
|
|
owsFailDebug("Couldn't load image: \(imageName)")
|
|
return
|
|
}
|
|
setTemplateImage(image, tintColor: tintColor)
|
|
}
|
|
|
|
class func withTemplateImage(_ templateImage: UIImage?, tintColor: UIColor) -> UIImageView {
|
|
let imageView = UIImageView()
|
|
imageView.setTemplateImage(templateImage, tintColor: tintColor)
|
|
return imageView
|
|
}
|
|
|
|
class func withTemplateImageName(_ imageName: String, tintColor: UIColor) -> UIImageView {
|
|
let imageView = UIImageView()
|
|
imageView.setTemplateImageName(imageName, tintColor: tintColor)
|
|
return imageView
|
|
}
|
|
}
|
|
|
|
// MARK: -
|
|
|
|
public extension UIImage {
|
|
|
|
func asTintedImage(color: UIColor) -> UIImage? {
|
|
let template = self.withRenderingMode(.alwaysTemplate)
|
|
let imageView = UIImageView(image: template)
|
|
imageView.tintColor = color
|
|
|
|
return imageView.renderAsImage(opaque: imageView.isOpaque, scale: UIScreen.main.scale)
|
|
}
|
|
|
|
/// Redraw the image into a new image, with an added background color, and inset the
|
|
/// original image by the provided insets.
|
|
func withBackgroundColor(_ color: UIColor, insets: UIEdgeInsets = .zero) -> UIImage? {
|
|
UIGraphicsBeginImageContextWithOptions(size, true, scale)
|
|
defer {
|
|
UIGraphicsEndImageContext()
|
|
}
|
|
|
|
guard let ctx = UIGraphicsGetCurrentContext(), let image = cgImage else {
|
|
owsFailDebug("Failed to create image context when setting image background")
|
|
return nil
|
|
}
|
|
|
|
let rect = CGRect(origin: .zero, size: size)
|
|
ctx.setFillColor(color.cgColor)
|
|
ctx.fill(rect)
|
|
// draw the background behind
|
|
ctx.concatenate(CGAffineTransform(a: 1, b: 0, c: 0, d: -1, tx: 0, ty: size.height))
|
|
ctx.draw(image, in: rect.inset(by: insets))
|
|
|
|
guard let newImage = UIGraphicsGetImageFromCurrentImageContext() else {
|
|
owsFailDebug("Failed to create background-colored image from context")
|
|
return nil
|
|
}
|
|
return newImage
|
|
}
|
|
}
|
|
|
|
// MARK: -
|
|
|
|
public extension UIView {
|
|
|
|
func renderAsImage() -> UIImage {
|
|
renderAsImage(opaque: false, scale: UIScreen.main.scale)
|
|
}
|
|
|
|
func renderAsImage(opaque: Bool, scale: CGFloat) -> UIImage {
|
|
let format = UIGraphicsImageRendererFormat()
|
|
format.scale = scale
|
|
format.opaque = opaque
|
|
let renderer = UIGraphicsImageRenderer(bounds: self.bounds,
|
|
format: format)
|
|
return renderer.image { (context) in
|
|
self.layer.render(in: context.cgContext)
|
|
}
|
|
}
|
|
}
|