mirror of
https://github.com/SideStore/SideStore.git
synced 2026-02-08 22:33:26 +01:00
151 lines
4.5 KiB
Swift
151 lines
4.5 KiB
Swift
//
|
|
// VibrantButton.swift
|
|
// AltStore
|
|
//
|
|
// Created by Riley Testut on 3/22/23.
|
|
// Copyright © 2023 Riley Testut. All rights reserved.
|
|
//
|
|
|
|
import UIKit
|
|
|
|
private let preferredFont = UIFont.boldSystemFont(ofSize: 14)
|
|
|
|
class VibrantButton: UIButton
|
|
{
|
|
var title: String? {
|
|
didSet {
|
|
if #available(iOS 15, *)
|
|
{
|
|
self.configuration?.title = self.title
|
|
}
|
|
else
|
|
{
|
|
self.setTitle(self.title, for: .normal)
|
|
}
|
|
}
|
|
}
|
|
|
|
var image: UIImage? {
|
|
didSet {
|
|
if #available(iOS 15, *)
|
|
{
|
|
self.configuration?.image = self.image
|
|
}
|
|
else
|
|
{
|
|
self.setImage(self.image, for: .normal)
|
|
}
|
|
}
|
|
}
|
|
|
|
var contentInsets: NSDirectionalEdgeInsets = .zero {
|
|
didSet {
|
|
if #available(iOS 15, *)
|
|
{
|
|
self.configuration?.contentInsets = self.contentInsets
|
|
}
|
|
else
|
|
{
|
|
self.contentEdgeInsets = UIEdgeInsets(top: self.contentInsets.top, left: self.contentInsets.leading, bottom: self.contentInsets.bottom, right: self.contentInsets.trailing)
|
|
}
|
|
}
|
|
}
|
|
|
|
override var isIndicatingActivity: Bool {
|
|
didSet {
|
|
guard #available(iOS 15, *) else { return }
|
|
self.updateConfiguration()
|
|
}
|
|
}
|
|
|
|
private let vibrancyView = UIVisualEffectView(effect: nil)
|
|
|
|
override init(frame: CGRect)
|
|
{
|
|
super.init(frame: frame)
|
|
|
|
self.initialize()
|
|
}
|
|
|
|
required init?(coder: NSCoder)
|
|
{
|
|
super.init(coder: coder)
|
|
|
|
self.initialize()
|
|
}
|
|
|
|
private func initialize()
|
|
{
|
|
let blurEffect = UIBlurEffect(style: .systemThinMaterial)
|
|
let vibrancyEffect = UIVibrancyEffect(blurEffect: blurEffect, style: .fill) // .fill is more vibrant than .secondaryLabel
|
|
|
|
if #available(iOS 15, *)
|
|
{
|
|
var backgroundConfig = UIBackgroundConfiguration.clear()
|
|
backgroundConfig.visualEffect = blurEffect
|
|
|
|
var config = UIButton.Configuration.plain()
|
|
config.cornerStyle = .capsule
|
|
config.background = backgroundConfig
|
|
config.titleTextAttributesTransformer = UIConfigurationTextAttributesTransformer { [weak self] (attributes) in
|
|
var attributes = attributes
|
|
attributes.font = preferredFont
|
|
|
|
if let self, self.isIndicatingActivity
|
|
{
|
|
// Hide title when indicating activity, but without changing intrinsicContentSize.
|
|
attributes.foregroundColor = UIColor.clear
|
|
}
|
|
|
|
return attributes
|
|
}
|
|
|
|
self.configuration = config
|
|
}
|
|
else
|
|
{
|
|
self.clipsToBounds = true
|
|
self.contentInsets = NSDirectionalEdgeInsets(top: 8, leading: 8, bottom: 8, trailing: 8) // Add padding.
|
|
|
|
let blurView = UIVisualEffectView(effect: blurEffect)
|
|
blurView.isUserInteractionEnabled = false
|
|
self.addSubview(blurView, pinningEdgesWith: .zero)
|
|
self.insertSubview(blurView, at: 0)
|
|
}
|
|
|
|
self.vibrancyView.effect = vibrancyEffect
|
|
self.vibrancyView.isUserInteractionEnabled = false
|
|
self.addSubview(self.vibrancyView, pinningEdgesWith: .zero)
|
|
}
|
|
|
|
override func layoutSubviews()
|
|
{
|
|
super.layoutSubviews()
|
|
|
|
self.layer.cornerRadius = self.bounds.midY
|
|
|
|
// Make sure content subviews are inside self.vibrancyView.contentView.
|
|
|
|
if let titleLabel = self.titleLabel, titleLabel.superview != self.vibrancyView.contentView
|
|
{
|
|
self.vibrancyView.contentView.addSubview(titleLabel)
|
|
}
|
|
|
|
if let imageView = self.imageView, imageView.superview != self.vibrancyView.contentView
|
|
{
|
|
self.vibrancyView.contentView.addSubview(imageView)
|
|
}
|
|
|
|
if self.activityIndicatorView.superview != self.vibrancyView.contentView
|
|
{
|
|
self.vibrancyView.contentView.addSubview(self.activityIndicatorView)
|
|
}
|
|
|
|
if #unavailable(iOS 15)
|
|
{
|
|
// Update font after init because the original titleLabel is replaced.
|
|
self.titleLabel?.font = preferredFont
|
|
}
|
|
}
|
|
}
|