Skip to content

Instantly share code, notes, and snippets.

@ipefixe
Created August 14, 2017 11:12
Show Gist options
  • Save ipefixe/d5eee93da88a63253898d8589b35b4af to your computer and use it in GitHub Desktop.
Save ipefixe/d5eee93da88a63253898d8589b35b4af to your computer and use it in GitHub Desktop.
import UIKit
@IBDesignable
public final class DeluxeButton: UIControl {
//MARK: public
@IBInspectable
public var pressedBackgroundColor: UIColor = #colorLiteral(red: 0.8725044748, green: 0.1784299846, blue: 0.06712985019, alpha: 1)
@IBInspectable
public var unpressedBackgroundColor: UIColor = #colorLiteral(red: 0.2392156869, green: 0.6745098233, blue: 0.9686274529, alpha: 1) {
didSet {
backgroundColor = unpressedBackgroundColor
}
}
//MARK: fileprivate
fileprivate let imageView: UIImageView = {
let imageView = UIImageView()
imageView.contentMode = .scaleAspectFit
return imageView
}()
fileprivate let label: UILabel = {
let label = UILabel()
label.font = UIFont.systemFont(ofSize: 40, weight: UIFontWeightHeavy)
label.textAlignment = .center
label.textColor = #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)
label.adjustsFontSizeToFitWidth = true
return label
}()
fileprivate lazy var stackView: UIStackView = {
let stackView = UIStackView(arrangedSubviews: [self.imageView, self.label])
stackView.axis = .vertical
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.isUserInteractionEnabled = false
return stackView
}()
//MARK: init
public required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
initPhase2()
}
public override init(frame: CGRect) {
super.init(frame: frame)
initPhase2()
}
private func initPhase2() {
label.backgroundColor = tintColor
layer.borderColor = tintColor.cgColor
layer.cornerRadius = 20
layer.borderWidth = 10
addSubview(stackView)
NSLayoutConstraint.activate([
stackView.topAnchor.constraint(equalTo: layoutMarginsGuide.topAnchor),
stackView.bottomAnchor.constraint(equalTo: layoutMarginsGuide.bottomAnchor),
stackView.leftAnchor.constraint(equalTo: layoutMarginsGuide.leftAnchor),
stackView.rightAnchor.constraint(equalTo: layoutMarginsGuide.rightAnchor),
label.heightAnchor.constraint(equalTo: heightAnchor, multiplier: 0.3)
])
}
override public func tintColorDidChange() {
label.backgroundColor = tintColor
layer.borderColor = tintColor.cgColor
}
}
//MARK: public attributes of Deluxe Button
public extension DeluxeButton {
@IBInspectable
var image: UIImage? {
get {
return imageView.image
}
set {
imageView.image = newValue?.withRenderingMode(.alwaysTemplate)
}
}
@IBInspectable
var text: String? {
get {
return label.text
}
set {
label.text = newValue
}
}
@IBInspectable
var borderWidth: CGFloat {
get {
return layer.borderWidth
}
set {
layoutMargins = UIEdgeInsets (top: newValue, left: newValue, bottom: newValue/2, right: newValue)
layer.borderWidth = newValue
}
}
@IBInspectable
var imagePadding: CGFloat {
get {
return image?.alignmentRectInsets.top ?? 0
}
set {
image = image?.withAlignmentRectInsets(UIEdgeInsets(top: -newValue, left: -newValue, bottom: -newValue, right: -newValue))
}
}
}
//MARK: UIControl
public extension DeluxeButton {
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
animate(isPressed: true)
}
override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesCancelled(touches, with: event)
animate(isPressed: false)
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesEnded(touches, with: event)
animate(isPressed: false)
}
private func animate(isPressed: Bool) {
let (duration, backgroundColor) = {
isPressed ? (duration: 0.05, backgroundColor: pressedBackgroundColor) : (duration: 0.2, backgroundColor: unpressedBackgroundColor)
}()
UIView.animate(withDuration: duration) {
self.backgroundColor = backgroundColor
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment