Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
folium-app
GitHub Repository: folium-app/Folium
Path: blob/a-new-beginning/Folium-iOS/Classes/FakeButton.swift
2 views
//
//  FakeButton.swift
//  Folium-iOS
//
//  Created by Jarrod Norwell on 2/7/2025.
//

import UIKit

class FakeButton : UIView {
    var handler: ((FakeButton) -> Void)? = nil
    
    var visualEffectView: UIVisualEffectView? = nil
    var label: UILabel? = nil
    var imageView: UIImageView? = nil
    
    override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
        super.traitCollectionDidChange(previousTraitCollection)
        if #unavailable(iOS 17) {
            layer.borderColor = UIColor.secondarySystemBackground.cgColor
        }
    }
    
    init(image: UIImage? = nil, style: UIBlurEffect.Style = .private, frame: CGRect = .zero) {
        super.init(frame: frame)
        clipsToBounds = true
        layer.cornerCurve = .continuous
        if #unavailable(iOS 26) {
            layer.borderColor = UIColor.secondarySystemBackground.cgColor
            layer.borderWidth = 3
            if #available(iOS 17, *) {
                registerForTraitChanges([UITraitUserInterfaceStyle.self]) { (traitEnvironment: UITraitEnvironment, previousTraitCollection: UITraitCollection) in
                    self.layer.borderColor = UIColor.secondarySystemBackground.cgColor
                }
            }
        }
        
        visualEffectView = .init(effect: UIBlurEffect(style: style))
        guard let visualEffectView else {
            return
        }
        visualEffectView.translatesAutoresizingMaskIntoConstraints = false
        addSubview(visualEffectView)
        
        visualEffectView.topAnchor.constraint(equalTo: safeAreaLayoutGuide.topAnchor).isActive = true
        visualEffectView.leadingAnchor.constraint(equalTo: safeAreaLayoutGuide.leadingAnchor).isActive = true
        visualEffectView.bottomAnchor.constraint(equalTo: safeAreaLayoutGuide.bottomAnchor).isActive = true
        visualEffectView.trailingAnchor.constraint(equalTo: safeAreaLayoutGuide.trailingAnchor).isActive = true
        
        imageView = .init(image: image?.applyingSymbolConfiguration(.init(weight: .medium)))
        guard let imageView else {
            return
        }
        imageView.translatesAutoresizingMaskIntoConstraints = false
        imageView.contentMode = .scaleAspectFit
        imageView.tintColor = style == .systemMaterialLight ? .darkText : .label
        visualEffectView.contentView.addSubview(imageView)
        
        imageView.topAnchor.constraint(equalTo: visualEffectView.contentView.safeAreaLayoutGuide.topAnchor, constant: 12).isActive = true
        imageView.leadingAnchor.constraint(equalTo: visualEffectView.contentView.safeAreaLayoutGuide.leadingAnchor, constant: 12).isActive = true
        imageView.bottomAnchor.constraint(equalTo: visualEffectView.contentView.safeAreaLayoutGuide.bottomAnchor, constant: -12).isActive = true
        imageView.trailingAnchor.constraint(equalTo: visualEffectView.contentView.safeAreaLayoutGuide.trailingAnchor, constant: -12).isActive = true
        
        widthAnchor.constraint(equalToConstant: 50).isActive = true
        heightAnchor.constraint(equalTo: widthAnchor).isActive = true
    }
    
    init(text: String, style: UIBlurEffect.Style = .private, frame: CGRect = .zero) {
        super.init(frame: frame)
        clipsToBounds = true
        layer.cornerCurve = .continuous
        if #unavailable(iOS 26) {
            layer.borderColor = UIColor.secondarySystemBackground.cgColor
            layer.borderWidth = 3
            if #available(iOS 17, *) {
                registerForTraitChanges([UITraitUserInterfaceStyle.self]) { (traitEnvironment: UITraitEnvironment, previousTraitCollection: UITraitCollection) in
                    self.layer.borderColor = UIColor.secondarySystemBackground.cgColor
                }
            }
        }
        
        visualEffectView = .init(effect: UIBlurEffect(style: style))
        guard let visualEffectView else {
            return
        }
        visualEffectView.translatesAutoresizingMaskIntoConstraints = false
        addSubview(visualEffectView)
        
        visualEffectView.topAnchor.constraint(equalTo: safeAreaLayoutGuide.topAnchor).isActive = true
        visualEffectView.leadingAnchor.constraint(equalTo: safeAreaLayoutGuide.leadingAnchor).isActive = true
        visualEffectView.bottomAnchor.constraint(equalTo: safeAreaLayoutGuide.bottomAnchor).isActive = true
        visualEffectView.trailingAnchor.constraint(equalTo: safeAreaLayoutGuide.trailingAnchor).isActive = true
        
        label = .init()
        guard let label else {
            return
        }
        label.translatesAutoresizingMaskIntoConstraints = false
        label.font = .bold(.body)
        label.text = text
        label.textAlignment = .center
        label.textColor = style == .systemMaterialLight ? .darkText : .label
        visualEffectView.contentView.addSubview(label)
        
        label.centerYAnchor.constraint(equalTo: safeAreaLayoutGuide.centerYAnchor).isActive = true
        label.leadingAnchor.constraint(equalTo: visualEffectView.contentView.safeAreaLayoutGuide.leadingAnchor, constant: 20).isActive = true
        label.trailingAnchor.constraint(equalTo: visualEffectView.contentView.safeAreaLayoutGuide.trailingAnchor, constant: -20).isActive = true
        
        heightAnchor.constraint(equalToConstant: 50).isActive = true
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        layer.cornerRadius = frame.height / 2
    }
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        super.touchesBegan(touches, with: event)
        guard let handler else {
            return
        }
        
        handler(self)
    }
    
    func set(text: String? = nil) {
        guard let label else {
            return
        }
        
        label.text = text
    }
    
    @available(iOS 17, *)
    func set(image: UIImage? = nil, with transition: some ContentTransitionSymbolEffect & SymbolEffect) {
        guard let imageView, let image else {
            return
        }
        
        imageView.setSymbolImage(image, contentTransition: transition)
    }
}