func drawRectangle() {
let renderer = UIGraphicsImageRenderer(size: CGSize(width: 300, height: 300))
let img = renderer.image { ctx in
let rectangle = CGRect(x: 0, y: 0, width: 300, height: 300)
ctx.cgContext.setFillColor(UIColor.red.cgColor)
ctx.cgContext.setStrokeColor(UIColor.green.cgColor)
ctx.cgContext.setLineWidth(10)
ctx.cgContext.addRect(rectangle)
ctx.cgContext.drawPath(using: .fillStroke)
}
imageView.image = img
}
func drawRectangle2() {
let renderer = UIGraphicsImageRenderer(size: CGSize(width: 300, height: 300))
let img = renderer.image { ctx in
ctx.cgContext.setFillColor(UIColor.red.cgColor)
ctx.cgContext.fill(CGRect(x: 0, y: 0, width: 300, height: 300))
}
imageView.image = img
}
func drawCircle() {
let renderer = UIGraphicsImageRenderer(size: CGSize(width: 300, height: 300))
let img = renderer.image { ctx in
ctx.cgContext.setFillColor(UIColor.red.cgColor)
ctx.cgContext.setStrokeColor(UIColor.green.cgColor)
ctx.cgContext.setLineWidth(10)
let rectangle = CGRect(x: 0, y: 0, width: 300, height: 300).inset(by: UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10))
ctx.cgContext.addEllipse(in: rectangle)
ctx.cgContext.drawPath(using: .fillStroke)
}
imageView.image = img
}
> Note: Circles need to be inset because they draw up to rectangle edge
func drawRotatedSquare() {
let renderer = UIGraphicsImageRenderer(size: CGSize(width: 256, height: 256))
let img = renderer.image { ctx in
ctx.cgContext.translateBy(x: 128, y: 128)
let rotations = 16
let amount = Double.pi / Double(rotations)
// add 16 rotated rectangles
for _ in 0 ..< rotations {
ctx.cgContext.rotate(by: CGFloat(amount))
ctx.cgContext.addRect(CGRect(x: -64, y: -64, width: 128, height: 128))
}
ctx.cgContext.setStrokeColor(UIColor.systemRed.cgColor)
ctx.cgContext.strokePath()
}
imageView.image = img
}
func drawLines() {
let renderer = UIGraphicsImageRenderer(size: CGSize(width: 256, height: 256))
let img = renderer.image { ctx in
ctx.cgContext.translateBy(x: 128, y: 128)
var first = true
var length: CGFloat = 128
for _ in 0 ..< 128 {
ctx.cgContext.rotate(by: .pi / 2)
if first {
ctx.cgContext.move(to: CGPoint(x: length, y: 25))
first = false
} else {
ctx.cgContext.addLine(to: CGPoint(x: length, y: 25))
}
length *= 0.99
}
ctx.cgContext.setStrokeColor(UIColor.systemRed.cgColor)
ctx.cgContext.strokePath()
}
imageView.image = img
}
func drawImagesAndText() {
let renderer = UIGraphicsImageRenderer(size: CGSize(width: 256, height: 256))
let img = renderer.image { ctx in
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = .center
let attrs: [NSAttributedString.Key: Any] = [
.font: UIFont.preferredFont(forTextStyle: .title1),
.paragraphStyle: paragraphStyle
]
let string = "The best laid schemes of mince and men"
let attributedString = NSAttributedString(string: string, attributes: attrs)
attributedString.draw(with: CGRect(x: 32, y: 32, width: 200, height: 200), options: .usesLineFragmentOrigin, context: nil)
let star = UIImage(named: "star")
star?.draw(at: CGPoint(x: 124, y: 150))
}
imageView.image = img
}
import UIKit
class GraphView: UIView {
let imageView = UIImageView()
override init(frame: CGRect) {
super.init(frame: .zero)
backgroundColor = .systemYellow
layout()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func layout() {
imageView.translatesAutoresizingMaskIntoConstraints = false
drawRectangle()
addSubview(imageView)
NSLayoutConstraint.activate([
imageView.centerXAnchor.constraint(equalTo: centerXAnchor),
imageView.centerYAnchor.constraint(equalTo: centerYAnchor),
])
}
func drawRectangle() { ... }
}
import UIKit
class ViewController: UIViewController {
let label = GradientLabel()
override func viewDidLoad() {
super.viewDidLoad()
style()
layout()
}
func style() {
label.translatesAutoresizingMaskIntoConstraints = false
label.font = UIFont.preferredFont(forTextStyle: .title1).bold()
label.numberOfLines = 0
label.lineBreakMode = .byWordWrapping
label.text = "A NEW WAY TO WORK HAS ARRIVED"
label.gradientColors = [UIColor.blue.cgColor, UIColor.red.cgColor]
}
func layout() {
view.addSubview(label)
NSLayoutConstraint.activate([
label.centerXAnchor.constraint(equalTo: view.centerXAnchor),
label.centerYAnchor.constraint(equalTo: view.centerYAnchor),
label.widthAnchor.constraint(equalToConstant: 300)
])
}
}
extension UIFont {
func withTraits(traits: UIFontDescriptor.SymbolicTraits) -> UIFont {
let descriptor = fontDescriptor.withSymbolicTraits(traits)
return UIFont(descriptor: descriptor!, size: 0) //size 0 means keep the size as it is
}
func bold() -> UIFont {
return withTraits(traits: .traitBold)
}
}
class GradientLabel: UILabel {
var gradientColors: [CGColor] = []
override func drawText(in rect: CGRect) {
if let gradientColor = drawGradientColor(in: rect, colors: gradientColors) {
self.textColor = gradientColor
}
super.drawText(in: rect)
}
private func drawGradientColor(in rect: CGRect, colors: [CGColor]) -> UIColor? {
let currentContext = UIGraphicsGetCurrentContext()
currentContext?.saveGState()
defer { currentContext?.restoreGState() }
let size = rect.size
UIGraphicsBeginImageContextWithOptions(size, false, 0)
guard let gradient = CGGradient(colorsSpace: CGColorSpaceCreateDeviceRGB(),
colors: colors as CFArray,
locations: nil) else { return nil }
let context = UIGraphicsGetCurrentContext()
context?.drawLinearGradient(gradient,
start: CGPoint.zero,
end: CGPoint(x: size.width, y: 0),
options: [])
let gradientImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
guard let image = gradientImage else { return nil }
return UIColor(patternImage: image)
}
}
OnView.swift
import UIKit
class OnView: UIView {
let size: CGFloat = 16
let lineWidth: CGFloat = 2
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = .white
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func draw(_ rect: CGRect) {
guard let context = UIGraphicsGetCurrentContext() else { return }
// outer
let outerBounds = CGRect(x: 0, y: 0, width: size, height: size).insetBy(dx: lineWidth/2, dy: lineWidth/2)
context.setFillColor(UIColor.black.cgColor)
context.setStrokeColor(UIColor.black.cgColor)
context.setLineWidth(lineWidth)
context.addEllipse(in: outerBounds)
context.drawPath(using: .fillStroke)
// inner
let shrinkage: CGFloat = 0.6
let innerBounds = CGRect(x: (size - size*shrinkage)/2,
y: (size - size*shrinkage)/2,
width: size*shrinkage,
height: size*shrinkage)
context.setFillColor(UIColor.black.cgColor)
context.setStrokeColor(UIColor.white.cgColor)
context.setLineWidth(lineWidth)
context.addEllipse(in: innerBounds)
context.drawPath(using: .fillStroke)
}
override var intrinsicContentSize: CGSize {
return CGSize(width: size, height: size)
}
}
OffView.swift
import Foundation
import UIKit
class OffView: UIView {
let size: CGFloat = 16
let lineWidth: CGFloat = 2
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = .white
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func draw(_ rect: CGRect) {
guard let context = UIGraphicsGetCurrentContext() else { return }
let rectangle2 = CGRect(x: 0, y: 0, width: size, height: size).insetBy(dx: lineWidth/2, dy: lineWidth/2)
context.setFillColor(UIColor.white.cgColor)
context.setStrokeColor(UIColor.black.cgColor)
context.setLineWidth(lineWidth)
context.addEllipse(in: rectangle2)
context.drawPath(using: .fillStroke)
}
override var intrinsicContentSize: CGSize {
return CGSize(width: size, height: size)
}
}