185 lines
6.7 KiB
Swift
185 lines
6.7 KiB
Swift
//
|
|
// CommonSwitch.swift
|
|
// Wallet
|
|
//
|
|
// Created by Igor on 11.02.2021.
|
|
// Copyright © 2021 AM. All rights reserved.
|
|
//
|
|
|
|
import UIKit
|
|
|
|
class CommonSwitch: CommonControlCustom {
|
|
|
|
@IBOutlet private weak var actionBtn: UIButton!
|
|
@IBOutlet private weak var backBtn: UIButton!
|
|
@IBOutlet private weak var backPosition: NSLayoutConstraint!
|
|
@IBOutlet private weak var frontBtn: UIButton!
|
|
@IBOutlet private weak var frontPosition: NSLayoutConstraint!
|
|
@IBOutlet private weak var frontHeight: NSLayoutConstraint!
|
|
private var switchWidth: NSLayoutConstraint!
|
|
|
|
@IBInspectable var cornerRadius: CGFloat = 10 {
|
|
didSet { updateContent() }
|
|
}
|
|
private var _isSelected: Bool = false
|
|
override open var isSelected: Bool {
|
|
get { _isSelected }
|
|
set { set(isSelected: newValue, animated: false) }
|
|
}
|
|
func set(isSelected: Bool, animated: Bool) {
|
|
guard _isSelected != isSelected else { return }
|
|
_isSelected = isSelected
|
|
update(animated: animated)
|
|
}
|
|
@IBInspectable var frontInset: CGFloat = 0 {
|
|
didSet { updateContent() }
|
|
}
|
|
@IBInspectable var isLight: Bool = false {
|
|
didSet { updateContent() }
|
|
}
|
|
@IBInspectable var isActive: Bool = false {
|
|
didSet { updateContent() }
|
|
}
|
|
@IBInspectable var imageBack: UIImage? {
|
|
didSet { updateContent() }
|
|
}
|
|
@IBInspectable var lzTextBack: String? {
|
|
didSet { updateContent() }
|
|
}
|
|
@IBInspectable var imageBackSelected: UIImage? {
|
|
didSet { updateContent() }
|
|
}
|
|
@IBInspectable var lzTextBackSelected: String? {
|
|
didSet { updateContent() }
|
|
}
|
|
@IBInspectable var imageFront: UIImage? {
|
|
didSet { updateContent() }
|
|
}
|
|
@IBInspectable var lzTextFront: String? {
|
|
didSet { updateContent() }
|
|
}
|
|
@IBInspectable var imageFrontSelected: UIImage? {
|
|
didSet { updateContent() }
|
|
}
|
|
@IBInspectable var lzTextFrontSelected: String? {
|
|
didSet { updateContent() }
|
|
}
|
|
|
|
@IBInspectable var canChange: Bool = true
|
|
|
|
func toggle(animated: Bool = true) {
|
|
_isSelected = !isSelected
|
|
update(animated: animated)
|
|
}
|
|
|
|
private func updateContent() {
|
|
if isActive {
|
|
backgroundColor = isLight ? Asset.marble.color : Asset.deepWater.color
|
|
} else {
|
|
backgroundColor = Asset.disabled.color
|
|
}
|
|
layer.cornerRadius = cornerRadius
|
|
|
|
backBtn.contentEdgeInsets = .init(top: 0, left: 8, bottom: 0, right: 8)
|
|
frontBtn.contentEdgeInsets = .init(top: 0, left: 8, bottom: 0, right: 8)
|
|
|
|
frontBtn.backgroundColor = isLight ? Asset.deepWater.color : Asset.snow.color
|
|
frontBtn.layer.cornerRadius = cornerRadius - frontInset
|
|
frontBtn.clipsToBounds = true
|
|
frontBtn.contentEdgeInsets = .init(top: 0, left: 4, bottom: 0, right: 4)
|
|
frontHeight.constant = frame.size.height - frontInset*2
|
|
|
|
self.isUserInteractionEnabled = isActive
|
|
self.isEnabled = isActive
|
|
|
|
layoutIfNeeded()
|
|
update(animated: false)
|
|
}
|
|
|
|
private func update(animated: Bool) {
|
|
backPosition.constant = 0
|
|
frontPosition.constant = 0
|
|
if animated {
|
|
UIView.animate(withDuration: Animation.fastest) {
|
|
self.layoutIfNeeded()
|
|
} completion: { _ in
|
|
self.updateComplete(animated: true)
|
|
}
|
|
} else {
|
|
updateComplete(animated: false)
|
|
}
|
|
}
|
|
|
|
override func layoutSubviews() {
|
|
super.layoutSubviews()
|
|
if switchWidth != nil, widthConstraint() != nil {
|
|
updateComplete(animated: true)
|
|
}
|
|
}
|
|
|
|
private func widthConstraint() -> NSLayoutConstraint? {
|
|
constraints.filter({
|
|
NSStringFromClass($0.classForCoder) != "NSAutoresizingMaskLayoutConstraint"
|
|
&& $0.firstAttribute == .width
|
|
&& $0.priority.rawValue >= (switchWidth?.priority.rawValue ?? 0)
|
|
&& $0 != switchWidth
|
|
}).first
|
|
}
|
|
|
|
private func updateComplete(animated: Bool) {
|
|
let backTextColor = isLight ? Asset.textGranite.color : Asset.textSnow.color
|
|
let frontTextColor = isLight ? Asset.textSnow.color : Asset.textGranite.color
|
|
|
|
backBtn.setImage(isSelected ? imageBackSelected : imageBack, for: .normal)
|
|
backBtn.setAttributedTitle(
|
|
(isSelected ? lzTextBackSelected : lzTextBack)?.localized.attributed(style: .medium, size: 14, color: backTextColor),
|
|
for: .normal
|
|
)
|
|
if backBtn.image(for: .normal) != nil, backBtn.attributedTitle(for: .normal) != nil {
|
|
backBtn.titleEdgeInsets = .init(top: 0, left: 4, bottom: 0, right: 0)
|
|
backBtn.imageEdgeInsets = .init(top: 0, left: 0, bottom: 0, right: 4)
|
|
} else {
|
|
backBtn.titleEdgeInsets = .zero
|
|
backBtn.imageEdgeInsets = .zero
|
|
}
|
|
frontBtn.setImage(isSelected ? imageFrontSelected : imageFront, for: .normal)
|
|
frontBtn.setAttributedTitle(
|
|
(isSelected ? lzTextFrontSelected : lzTextFront)?.localized.attributed(style: .medium, size: 14, color: frontTextColor),
|
|
for: .normal
|
|
)
|
|
if frontBtn.image(for: .normal) != nil, frontBtn.attributedTitle(for: .normal) != nil {
|
|
frontBtn.titleEdgeInsets = .init(top: 0, left: 4, bottom: 0, right: 0)
|
|
frontBtn.imageEdgeInsets = .init(top: 0, left: 0, bottom: 0, right: 4)
|
|
} else {
|
|
frontBtn.titleEdgeInsets = .zero
|
|
frontBtn.imageEdgeInsets = .zero
|
|
}
|
|
if let constraint = widthConstraint(), switchWidth != nil {
|
|
removeConstraint(switchWidth)
|
|
switchWidth = constraint
|
|
}
|
|
layoutIfNeeded()
|
|
let width = backBtn.frame.width + frontBtn.frame.width + frontInset*2
|
|
if switchWidth == nil {
|
|
switchWidth = widthConstraint() ?? widthAnchor.constraint(equalToConstant: width)
|
|
switchWidth.isActive = true
|
|
}
|
|
switchWidth.constant = width
|
|
backPosition.constant = (isSelected ? -width + backBtn.frame.width : width - backBtn.frame.width)/2
|
|
frontPosition.constant = (isSelected ? width - frontBtn.frame.width - frontInset*2 : -width + frontBtn.frame.width + frontInset*2)/2
|
|
frontHeight.constant = frame.height - frontInset*2
|
|
animated ? UIView.animate(withDuration: Animation.fastest) { self.layoutIfNeeded() } : layoutIfNeeded()
|
|
}
|
|
|
|
@IBAction func onChangeState(_: AnyObject?) {
|
|
frontBtn.isHighlighted = actionBtn.isHighlighted
|
|
}
|
|
|
|
@IBAction func onToggle(_: AnyObject?) {
|
|
frontBtn.isHighlighted = actionBtn.isHighlighted
|
|
if canChange { toggle(animated: true) }
|
|
sendActions(for: .valueChanged)
|
|
}
|
|
|
|
}
|