Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save narciszait/ac8bacc78a75e5d8ff6b0fa35ec0796f to your computer and use it in GitHub Desktop.
Save narciszait/ac8bacc78a75e5d8ff6b0fa35ec0796f to your computer and use it in GitHub Desktop.
Custom progress bar with text
//
// PlainHorizontalProgressBar.swift
//
// Created by Julia Nikitina on 23.05.2020.
// Copyright © 2020 Julia Nikitina. All rights reserved.
//
import UIKit
@IBDesignable
final class PlainHorizontalProgressBar: UIView {
@IBInspectable
private var color: UIColor? = .systemPurple
var progress: CGFloat = 0.0 {
didSet {
setNeedsDisplay()
}
}
private let progressLayer = CALayer()
private let yellowTextLayer = CATextLayer()
private let purpleTextLayer = CATextLayer()
private let yellowMaskLayer = CAShapeLayer()
private let purpleMaskLayer = CAShapeLayer()
override init(frame: CGRect) {
super.init(frame: frame)
setupTextLayers()
setupProgressLayer()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
setupTextLayers()
setupProgressLayer()
}
override func draw(_ rect: CGRect) {
let progressRect = CGRect(
origin: .zero,
size: CGSize(width: bounds.width * progress, height: bounds.height)
)
let leftProgressRect = CGRect(
origin: CGPoint(x: bounds.width * progress, y: 0),
size: CGSize(width: bounds.width - bounds.width * progress, height: bounds.height)
)
let yellowMask = createMaskLayer(layer: yellowMaskLayer, leftProgressRect)
let purpleMask = createMaskLayer(layer: purpleMaskLayer, progressRect)
yellowTextLayer.mask = yellowMask
purpleTextLayer.mask = purpleMask
progressLayer.frame = progressRect
}
private func setupProgressLayer() {
layer.addSublayer(progressLayer)
progressLayer.backgroundColor = color?.cgColor
let backgroundMask = CAShapeLayer()
backgroundMask.path = UIBezierPath(roundedRect: bounds, cornerRadius: bounds.height * 0.25).cgPath
layer.mask = backgroundMask
}
private func setupTextLayers() {
[yellowTextLayer, purpleTextLayer].forEach {
$0.string = "Optimization..."
$0.fontSize = 17
$0.contentsScale = UIScreen.main.scale
$0.alignmentMode = .center
$0.frame = bounds
layer.addSublayer($0)
}
yellowTextLayer.foregroundColor = UIColor.systemYellow.cgColor
purpleTextLayer.foregroundColor = UIColor.systemPurple.cgColor
}
private func createMaskLayer(layer: CAShapeLayer, _ holeRect: CGRect) -> CAShapeLayer {
let path = CGMutablePath()
path.addRect(holeRect)
path.addRect(bounds)
layer.path = path
layer.fillRule = .evenOdd
layer.opacity = 1
return layer
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment