mirror of
https://github.com/SideStore/SideStore.git
synced 2026-02-10 15:23:27 +01:00
XCode project for app, moved app project to folder
This commit is contained in:
172
SideStoreApp/Sources/SideStoreAppKit/Components/PillButton.swift
Normal file
172
SideStoreApp/Sources/SideStoreAppKit/Components/PillButton.swift
Normal file
@@ -0,0 +1,172 @@
|
||||
//
|
||||
// PillButton.swift
|
||||
// AltStore
|
||||
//
|
||||
// Created by Riley Testut on 7/15/19.
|
||||
// Copyright © 2019 Riley Testut. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
final class PillButton: UIButton {
|
||||
override var accessibilityValue: String? {
|
||||
get {
|
||||
guard progress != nil else { return super.accessibilityValue }
|
||||
return progressView.accessibilityValue
|
||||
}
|
||||
set { super.accessibilityValue = newValue }
|
||||
}
|
||||
|
||||
var progress: Progress? {
|
||||
didSet {
|
||||
progressView.progress = Float(progress?.fractionCompleted ?? 0)
|
||||
progressView.observedProgress = progress
|
||||
|
||||
let isUserInteractionEnabled = self.isUserInteractionEnabled
|
||||
isIndicatingActivity = (progress != nil)
|
||||
self.isUserInteractionEnabled = isUserInteractionEnabled
|
||||
|
||||
update()
|
||||
}
|
||||
}
|
||||
|
||||
var progressTintColor: UIColor? {
|
||||
get {
|
||||
progressView.progressTintColor
|
||||
}
|
||||
set {
|
||||
progressView.progressTintColor = newValue
|
||||
}
|
||||
}
|
||||
|
||||
var countdownDate: Date? {
|
||||
didSet {
|
||||
isEnabled = (countdownDate == nil)
|
||||
displayLink.isPaused = (countdownDate == nil)
|
||||
|
||||
if countdownDate == nil {
|
||||
setTitle(nil, for: .disabled)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private let progressView = UIProgressView(progressViewStyle: .default)
|
||||
|
||||
private lazy var displayLink: CADisplayLink = {
|
||||
let displayLink = CADisplayLink(target: self, selector: #selector(PillButton.updateCountdown))
|
||||
displayLink.preferredFramesPerSecond = 15
|
||||
displayLink.isPaused = true
|
||||
displayLink.add(to: .main, forMode: .common)
|
||||
return displayLink
|
||||
}()
|
||||
|
||||
private let dateComponentsFormatter: DateComponentsFormatter = {
|
||||
let dateComponentsFormatter = DateComponentsFormatter()
|
||||
dateComponentsFormatter.zeroFormattingBehavior = [.pad]
|
||||
dateComponentsFormatter.collapsesLargestUnit = false
|
||||
return dateComponentsFormatter
|
||||
}()
|
||||
|
||||
override var intrinsicContentSize: CGSize {
|
||||
var size = super.intrinsicContentSize
|
||||
size.width += 26
|
||||
size.height += 3
|
||||
return size
|
||||
}
|
||||
|
||||
deinit {
|
||||
self.displayLink.remove(from: .main, forMode: RunLoop.Mode.default)
|
||||
}
|
||||
|
||||
override func awakeFromNib() {
|
||||
super.awakeFromNib()
|
||||
|
||||
layer.masksToBounds = true
|
||||
accessibilityTraits.formUnion([.updatesFrequently, .button])
|
||||
|
||||
activityIndicatorView.style = .medium
|
||||
activityIndicatorView.isUserInteractionEnabled = false
|
||||
|
||||
progressView.progress = 0
|
||||
progressView.trackImage = UIImage()
|
||||
progressView.isUserInteractionEnabled = false
|
||||
addSubview(progressView)
|
||||
|
||||
update()
|
||||
}
|
||||
|
||||
override func layoutSubviews() {
|
||||
super.layoutSubviews()
|
||||
|
||||
progressView.bounds.size.width = bounds.width
|
||||
|
||||
let scale = bounds.height / progressView.bounds.height
|
||||
|
||||
progressView.transform = CGAffineTransform.identity.scaledBy(x: 1, y: scale)
|
||||
progressView.center = CGPoint(x: bounds.midX, y: bounds.midY)
|
||||
|
||||
layer.cornerRadius = bounds.midY
|
||||
}
|
||||
|
||||
override func tintColorDidChange() {
|
||||
super.tintColorDidChange()
|
||||
|
||||
update()
|
||||
}
|
||||
}
|
||||
|
||||
private extension PillButton {
|
||||
func update() {
|
||||
if progress == nil {
|
||||
setTitleColor(.white, for: .normal)
|
||||
backgroundColor = tintColor
|
||||
} else {
|
||||
setTitleColor(tintColor, for: .normal)
|
||||
backgroundColor = tintColor.withAlphaComponent(0.15)
|
||||
}
|
||||
|
||||
progressView.progressTintColor = tintColor
|
||||
}
|
||||
|
||||
@objc func updateCountdown() {
|
||||
guard let endDate = countdownDate else { return }
|
||||
|
||||
let startDate = Date()
|
||||
|
||||
let interval = endDate.timeIntervalSince(startDate)
|
||||
guard interval > 0 else {
|
||||
isEnabled = true
|
||||
return
|
||||
}
|
||||
|
||||
let text: String?
|
||||
|
||||
if interval < (1 * 60 * 60) {
|
||||
dateComponentsFormatter.unitsStyle = .positional
|
||||
dateComponentsFormatter.allowedUnits = [.minute, .second]
|
||||
|
||||
text = dateComponentsFormatter.string(from: startDate, to: endDate)
|
||||
} else if interval < (2 * 24 * 60 * 60) {
|
||||
dateComponentsFormatter.unitsStyle = .positional
|
||||
dateComponentsFormatter.allowedUnits = [.hour, .minute, .second]
|
||||
|
||||
text = dateComponentsFormatter.string(from: startDate, to: endDate)
|
||||
} else {
|
||||
dateComponentsFormatter.unitsStyle = .full
|
||||
dateComponentsFormatter.allowedUnits = [.day]
|
||||
|
||||
let numberOfDays = endDate.numberOfCalendarDays(since: startDate)
|
||||
text = String(format: NSLocalizedString("%@ DAYS", comment: ""), NSNumber(value: numberOfDays))
|
||||
}
|
||||
|
||||
if let text = text {
|
||||
UIView.performWithoutAnimation {
|
||||
self.isEnabled = false
|
||||
self.setTitle(text, for: .disabled)
|
||||
self.layoutIfNeeded()
|
||||
}
|
||||
} else {
|
||||
isEnabled = true
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user