// // UIView+Ext.swift // Lockdown // // Created by Alexander Parshakov on 9/6/22 // Copyright © 2022 Confirmed Inc. All rights reserved. // import Foundation import UIKit extension UIView { // MARK: - Gradient @discardableResult func applyGradient(_ gradient: LockdownGradient, corners: Corners = .continuous(0)) -> CAGradientLayer { let gradientLayer = CAGradientLayer() gradientLayer.colors = gradient.colors gradientLayer.startPoint = gradient.points.start gradientLayer.endPoint = gradient.points.end gradientLayer.frame = bounds gradientLayer.corners = corners self.corners = corners layer.sublayers?.first(where: { $0 is CAGradientLayer })?.removeFromSuperlayer() layer.insertSublayer(gradientLayer, at: 0) return gradientLayer } // MARK: - Animation func showAnimatedPress(duration: Double = 0.1, withScale scale: CGFloat = 0.95, completion: (() -> Void)? = nil) { isUserInteractionEnabled = false UIView.animate(withDuration: duration, animations: { self.transformToScale(scale) }) { _ in UIView.animate(withDuration: duration, animations: { self.transformToIdentity() }) { [weak self] isCompleted in self?.isUserInteractionEnabled = true guard isCompleted else { return } completion?() } } } func showAnimatedSpring(duration: Double = 0.1, withScale scale: CGFloat = 0.95, completion: (() -> Void)? = nil) { isUserInteractionEnabled = false UIView.animate(withDuration: duration, animations: { self.transformToScale(scale) }) { (_) in UIView.animate(withDuration: duration / 3, animations: { self.transformToIdentity() }) { [weak self] isCompleted in self?.isUserInteractionEnabled = true guard isCompleted else { return } completion?() } } } func transformToIdentity() { self.transform = CGAffineTransform.identity } private func transformToScale(_ scale: CGFloat) { transform = CGAffineTransform(scaleX: scale, y: scale) } func fadeIn(duration: CGFloat, completion: (() -> Void)? = nil) { self.alpha = 0 UIView.animate(withDuration: duration, animations: { self.alpha = 1 }, completion: { isContinued in guard isContinued else { return } completion?() }) } func fadeOut(duration: CGFloat, completion: (() -> Void)? = nil) { UIView.animate(withDuration: duration, animations: { self.alpha = 0 }, completion: { isContinued in guard isContinued else { return } completion?() }) } func fadeOutAsDiminished(duration: CGFloat, delay: CGFloat = 0, completion: (() -> Void)? = nil) { UIView.animate(withDuration: duration, delay: delay, animations: { self.transform = CGAffineTransform(scaleX: 0.01, y: 0.01) self.alpha = 0 }, completion: { isContinued in guard isContinued else { return } completion?() }) } func animateBorderWidth(toValue: CGFloat, duration: Double = 0.4, color: UIColor = .fromHex("#00ADE7")) { let animation = CABasicAnimation(keyPath: "borderWidth") animation.fromValue = layer.borderWidth animation.toValue = toValue animation.duration = duration layer.borderColor = color.cgColor layer.add(animation, forKey: "Width") layer.borderWidth = toValue } // MARK: - Shadow func dropShadow() { layer.masksToBounds = false layer.shadowColor = UIColor.black.cgColor layer.shadowOpacity = 0.12 layer.shadowOffset = CGSize(width: 1, height: 1) layer.shadowRadius = layer.cornerRadius layer.shadowPath = UIBezierPath(rect: self.bounds).cgPath layer.shouldRasterize = true layer.rasterizationScale = UIScreen.main.scale } } extension UIColor { static func fromHex(_ hex: String) -> UIColor { var cString:String = hex.trimmingCharacters(in: .whitespacesAndNewlines).uppercased() if cString.hasPrefix("#") { cString.remove(at: cString.startIndex) } if (cString.count) != 6 { return UIColor.gray } var rgbValue:UInt64 = 0 Scanner(string: cString).scanHexInt64(&rgbValue) return UIColor( red: CGFloat((rgbValue & 0xFF0000) >> 16) / 255.0, green: CGFloat((rgbValue & 0x00FF00) >> 8) / 255.0, blue: CGFloat(rgbValue & 0x0000FF) / 255.0, alpha: CGFloat(1.0) ) } static func dynamicColor(light: UIColor, dark: UIColor) -> UIColor { guard #available(iOS 13.0, *) else { return light } return UIColor { $0.userInterfaceStyle == .dark ? dark : light } } } class GradientView: UIView { var gradient: LockdownGradient? { didSet { guard let gradient else { return } gradientLayer = applyGradient(gradient) } } var gradientLayer: CALayer? override func layoutSubviews() { super.layoutSubviews() gradientLayer?.frame = bounds } }