mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-23 06:35:51 +00:00
Effect improvements
This commit is contained in:
@@ -0,0 +1,149 @@
|
||||
import Foundation
|
||||
import UIKit
|
||||
import Display
|
||||
import ComponentFlow
|
||||
import TelegramPresentationData
|
||||
|
||||
final class GroupHeaderActionButton: UIButton {
|
||||
override static var layerClass: AnyClass {
|
||||
return PassthroughLayer.self
|
||||
}
|
||||
|
||||
let tintContainerLayer: SimpleLayer
|
||||
|
||||
private var currentTextLayout: (string: String, color: UIColor, constrainedWidth: CGFloat, size: CGSize)?
|
||||
private let backgroundLayer: SimpleLayer
|
||||
private let tintBackgroundLayer: SimpleLayer
|
||||
private let textLayer: SimpleLayer
|
||||
private let tintTextLayer: SimpleLayer
|
||||
private let pressed: () -> Void
|
||||
|
||||
init(pressed: @escaping () -> Void) {
|
||||
self.pressed = pressed
|
||||
|
||||
self.tintContainerLayer = SimpleLayer()
|
||||
|
||||
self.backgroundLayer = SimpleLayer()
|
||||
self.backgroundLayer.masksToBounds = true
|
||||
|
||||
self.tintBackgroundLayer = SimpleLayer()
|
||||
self.tintBackgroundLayer.masksToBounds = true
|
||||
|
||||
self.textLayer = SimpleLayer()
|
||||
self.tintTextLayer = SimpleLayer()
|
||||
|
||||
super.init(frame: CGRect())
|
||||
|
||||
(self.layer as? PassthroughLayer)?.mirrorLayer = self.tintContainerLayer
|
||||
|
||||
self.layer.addSublayer(self.backgroundLayer)
|
||||
self.layer.addSublayer(self.textLayer)
|
||||
|
||||
self.addTarget(self, action: #selector(self.onPressed), for: .touchUpInside)
|
||||
|
||||
self.tintContainerLayer.addSublayer(self.tintBackgroundLayer)
|
||||
self.tintContainerLayer.addSublayer(self.tintTextLayer)
|
||||
}
|
||||
|
||||
required init(coder: NSCoder) {
|
||||
preconditionFailure()
|
||||
}
|
||||
|
||||
@objc private func onPressed() {
|
||||
self.pressed()
|
||||
}
|
||||
|
||||
override func beginTracking(_ touch: UITouch, with event: UIEvent?) -> Bool {
|
||||
self.alpha = 0.6
|
||||
|
||||
return super.beginTracking(touch, with: event)
|
||||
}
|
||||
|
||||
override func endTracking(_ touch: UITouch?, with event: UIEvent?) {
|
||||
let alpha = self.alpha
|
||||
self.alpha = 1.0
|
||||
self.layer.animateAlpha(from: alpha, to: 1.0, duration: 0.25)
|
||||
|
||||
super.endTracking(touch, with: event)
|
||||
}
|
||||
|
||||
override func cancelTracking(with event: UIEvent?) {
|
||||
let alpha = self.alpha
|
||||
self.alpha = 1.0
|
||||
self.layer.animateAlpha(from: alpha, to: 1.0, duration: 0.25)
|
||||
|
||||
super.cancelTracking(with: event)
|
||||
}
|
||||
|
||||
override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
|
||||
let alpha = self.alpha
|
||||
self.alpha = 1.0
|
||||
self.layer.animateAlpha(from: alpha, to: 1.0, duration: 0.25)
|
||||
|
||||
super.touchesCancelled(touches, with: event)
|
||||
}
|
||||
|
||||
func update(theme: PresentationTheme, title: String, compact: Bool) -> CGSize {
|
||||
let textConstrainedWidth: CGFloat = 100.0
|
||||
|
||||
let needsVibrancy = !theme.overallDarkAppearance && compact
|
||||
|
||||
let foregroundColor: UIColor
|
||||
let backgroundColor: UIColor
|
||||
|
||||
if compact {
|
||||
foregroundColor = theme.chat.inputMediaPanel.panelContentVibrantOverlayColor
|
||||
backgroundColor = foregroundColor.withMultipliedAlpha(0.2)
|
||||
} else {
|
||||
foregroundColor = theme.list.itemCheckColors.foregroundColor
|
||||
backgroundColor = theme.list.itemCheckColors.fillColor
|
||||
}
|
||||
|
||||
self.backgroundLayer.backgroundColor = backgroundColor.cgColor
|
||||
self.tintBackgroundLayer.backgroundColor = UIColor.white.withAlphaComponent(0.2).cgColor
|
||||
|
||||
self.tintContainerLayer.isHidden = !needsVibrancy
|
||||
|
||||
let textSize: CGSize
|
||||
if let currentTextLayout = self.currentTextLayout, currentTextLayout.string == title, currentTextLayout.color == foregroundColor, currentTextLayout.constrainedWidth == textConstrainedWidth {
|
||||
textSize = currentTextLayout.size
|
||||
} else {
|
||||
let font: UIFont = compact ? Font.medium(11.0) : Font.semibold(15.0)
|
||||
let string = NSAttributedString(string: title.uppercased(), font: font, textColor: foregroundColor)
|
||||
let tintString = NSAttributedString(string: title.uppercased(), font: font, textColor: .white)
|
||||
let stringBounds = string.boundingRect(with: CGSize(width: textConstrainedWidth, height: 100.0), options: .usesLineFragmentOrigin, context: nil)
|
||||
textSize = CGSize(width: ceil(stringBounds.width), height: ceil(stringBounds.height))
|
||||
self.textLayer.contents = generateImage(textSize, opaque: false, scale: 0.0, rotatedContext: { size, context in
|
||||
context.clear(CGRect(origin: CGPoint(), size: size))
|
||||
UIGraphicsPushContext(context)
|
||||
|
||||
string.draw(in: stringBounds)
|
||||
|
||||
UIGraphicsPopContext()
|
||||
})?.cgImage
|
||||
self.tintTextLayer.contents = generateImage(textSize, opaque: false, scale: 0.0, rotatedContext: { size, context in
|
||||
context.clear(CGRect(origin: CGPoint(), size: size))
|
||||
UIGraphicsPushContext(context)
|
||||
|
||||
tintString.draw(in: stringBounds)
|
||||
|
||||
UIGraphicsPopContext()
|
||||
})?.cgImage
|
||||
self.currentTextLayout = (title, foregroundColor, textConstrainedWidth, textSize)
|
||||
}
|
||||
|
||||
let size = CGSize(width: textSize.width + (compact ? 6.0 : 16.0) * 2.0, height: compact ? 16.0 : 28.0)
|
||||
|
||||
let textFrame = CGRect(origin: CGPoint(x: floor((size.width - textSize.width) / 2.0), y: floorToScreenPixels((size.height - textSize.height) / 2.0)), size: textSize)
|
||||
self.textLayer.frame = textFrame
|
||||
self.tintTextLayer.frame = textFrame
|
||||
|
||||
self.backgroundLayer.frame = CGRect(origin: CGPoint(), size: size)
|
||||
self.backgroundLayer.cornerRadius = min(size.width, size.height) / 2.0
|
||||
|
||||
self.tintBackgroundLayer.frame = self.backgroundLayer.frame
|
||||
self.tintBackgroundLayer.cornerRadius = self.backgroundLayer.cornerRadius
|
||||
|
||||
return size
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user