Skip to content

Instantly share code, notes, and snippets.

@krummler
Created April 20, 2020 12:20
Show Gist options
  • Save krummler/306adaa5a9c7280dfa18ffd3071e8149 to your computer and use it in GitHub Desktop.
Save krummler/306adaa5a9c7280dfa18ffd3071e8149 to your computer and use it in GitHub Desktop.
import UIKit
// MARK: Image helpers
extension UIImage {
struct Constants {
static let defaultTraits = [UITraitCollection(userInterfaceStyle: .dark),
UITraitCollection(userInterfaceStyle: .light)]
}
static func buttonBackground(color: UIColor,
borderColor: UIColor,
borderWidth: CGFloat,
cornerRadius: CGFloat,
traitCollections: [UITraitCollection] = Constants.defaultTraits) -> UIImage {
let set = UIImageAsset()
for trait in traitCollections {
let image = buttonBackground(color: color.resolvedColor(with: trait),
borderColor: borderColor.resolvedColor(with: trait),
borderWidth: borderWidth,
cornerRadius: cornerRadius)
let insets = image.size.width / 2
set.register(image.resizableImage(withCapInsets: UIEdgeInsets(top: insets, left: insets,
bottom: insets, right: insets)),
with: UITraitCollection(traitsFrom: [trait, UITraitCollection(displayScale: image.scale)]))
}
return set.image(with: UITraitCollection())
}
private static func from(color: UIColor,
size: CGSize = CGSize(width: 1, height: 1)) -> UIImage {
return UIGraphicsImageRenderer(size: size).image { context in
color.setFill()
context.fill(CGRect(origin: .zero, size: size))
}
}
private static func buttonBackground(color: UIColor,
borderColor: UIColor,
borderWidth: CGFloat,
cornerRadius: CGFloat) -> UIImage {
let width = max(2, cornerRadius * 2)
let size = CGSize(width: width, height: width)
return UIGraphicsImageRenderer(size: size).image { context in
color.setFill()
context.fill(CGRect(origin: .zero, size: size))
}.roundedBorder(color: borderColor,
width: borderWidth,
radius: cornerRadius)!
}
private func roundedBorder(color: UIColor, width: CGFloat, radius: CGFloat) -> UIImage? {
let format = imageRendererFormat
format.opaque = false
return UIGraphicsImageRenderer(size: size, format: format).image { _ in
let ovalPath = UIBezierPath(roundedRect: CGRect(origin: .zero, size: size), cornerRadius: radius)
ovalPath.addClip()
draw(at: .zero)
color.setStroke()
ovalPath.lineWidth = width
ovalPath.stroke()
}
}
}
// MARK: Implementation example
let backgroundColor = UIColor {
$0.userInterfaceStyle == .dark ?
UIColor(red: 10.0 / 255, green: 40.0 / 255, blue: 58.0 / 255, alpha: 1) :
UIColor(red: 183.0 / 255, green: 228.0 / 255, blue: 255.0 / 255, alpha: 1)
}
let borderColour = UIColor {
$0.userInterfaceStyle == .dark ?
UIColor(red: 197.0 / 255, green: 197.0 / 255, blue: 197.0 / 255, alpha: 1) :
UIColor(red: 0, green: 27.0 / 255, blue: 67.0 / 255, alpha: 1)
}
// MARK: Usage
let someImage = UIImage.buttonBackground(color: backgroundColor,
borderColor: borderColour,
borderWidth: 2,
cornerRadius: 8,
traitCollections: UIImage.Constants.defaultTraits)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment