Skip to content

Instantly share code, notes, and snippets.

@vialyx
Created June 8, 2018 18:57
Show Gist options
  • Save vialyx/d9d30db12de21704447494600edbcad2 to your computer and use it in GitHub Desktop.
Save vialyx/d9d30db12de21704447494600edbcad2 to your computer and use it in GitHub Desktop.
//
// SegmentView.swift
// CustomUIView
//
// Created by Maksim Vialykh on 08.06.2018.
// Copyright © 2018 Vialyx. All rights reserved.
//
import UIKit
@IBDesignable
final class SegmentView: UIView {
// MARK: - Properties
@IBInspectable
var cornerRadius: CGFloat {
set {
layer.cornerRadius = newValue
}
get {
return layer.cornerRadius
}
}
@IBInspectable
var segments: [String] = ["One", "Two", "..."]
@IBInspectable
var segmentColor: UIColor = .lightGray
@IBInspectable
var activeSegmentColor: UIColor = .darkGray
@IBInspectable
var textColor: UIColor = .black
@IBInspectable
var activeTextColor: UIColor = .white
@IBInspectable
var font: UIFont = .systemFont(ofSize: 18.0, weight: .medium)
@IBInspectable
var activeFont: UIFont = .systemFont(ofSize: 18.0, weight: .medium)
@IBInspectable
var activeIndex: Int = 0 {
didSet {
setNeedsDisplay()
}
}
// MARK: - Private properties
private lazy var paragraphStyle: NSParagraphStyle = {
let paragraph = NSParagraphStyle.default.mutableCopy() as! NSMutableParagraphStyle
paragraph.alignment = .center
return paragraph.copy() as! NSParagraphStyle
}()
private var segmentSize: CGFloat {
return frame.width / CGFloat(segments.count)
}
// MARK: - Initializers
override init(frame: CGRect) {
super.init(frame: frame)
configure()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
configure()
}
private func configure() {
addGestureRecognizer(
UITapGestureRecognizer(target: self, action: #selector(didTap(recognizer:)))
)
}
// MARK: - Actions
@objc
private func didTap(recognizer: UITapGestureRecognizer) {
let location = recognizer.location(in: self)
activeIndex = Int(location.x / segmentSize)
}
// MARK: - Drawing
override func draw(_ rect: CGRect) {
super.draw(rect)
guard let context = UIGraphicsGetCurrentContext() else { return }
/*
Draw background
*/
context.setFillColor(segmentColor.cgColor)
let backgroundPath = UIBezierPath(roundedRect: rect, cornerRadius: cornerRadius)
backgroundPath.fill()
/*
Enumerate segments property and call drawing function for each item
*/
segments.enumerated().forEach { index, title in
let rect = CGRect(x: CGFloat(index) * segmentSize, y: 0, width: segmentSize, height: frame.height)
if activeIndex == index {
/*
Draw background for active index
*/
context.setFillColor(activeSegmentColor.cgColor)
let path = UIBezierPath(roundedRect: rect, cornerRadius: cornerRadius)
path.fill()
draw(text: title, in: rect, with: activeTextColor, and: activeFont)
} else {
draw(text: title, in: rect, with: textColor, and: font)
}
}
}
private func draw(text: String, in rect: CGRect, with color: UIColor, and font: UIFont) {
/*
Draw text with incomming parameters
*/
var rect = rect
let attributes: [NSAttributedStringKey: Any] = [.font: font,
.foregroundColor: color,
.paragraphStyle: paragraphStyle]
let string = NSAttributedString(string: text, attributes: attributes)
let size = string.size()
rect.origin.y = (frame.height - size.height) / 2
rect.size.height = size.height
string.draw(in: rect)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment