Swiftgram/submodules/Display/Source/ListViewReorderingItemNode.swift
2021-08-11 01:28:16 +03:00

109 lines
4.5 KiB
Swift

import Foundation
import UIKit
import AsyncDisplayKit
private func generateShadowImage(mirror: Bool) -> UIImage? {
return generateImage(CGSize(width: 30.0, height: 45.0), rotatedContext: { size, context in
context.clear(CGRect(origin: CGPoint(), size: size))
if mirror {
context.translateBy(x: size.width / 2.0, y: size.height / 2.0)
context.scaleBy(x: 1.0, y: -1.0)
context.translateBy(x: -size.width / 2.0, y: -size.height / 2.0)
}
context.setShadow(offset: CGSize(width: 0.0, height: 0.0), blur: 18.0, color: UIColor(white: 0.0, alpha: 0.35).cgColor)
context.setFillColor(UIColor(white: 0.0, alpha: 1.0).cgColor)
for _ in 0 ..< 1 {
context.fill(CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: size.width, height: 15.0)))
}
context.clear(CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: size.width, height: 15.0)))
})
}
private final class CopyView: UIView {
let topShadow: UIImageView
let bottomShadow: UIImageView
init(frame: CGRect, hasShadow: Bool) {
self.topShadow = UIImageView()
self.bottomShadow = UIImageView()
super.init(frame: frame)
if hasShadow {
self.topShadow.image = generateShadowImage(mirror: true)
self.bottomShadow.image = generateShadowImage(mirror: false)
}
self.addSubview(self.topShadow)
self.addSubview(self.bottomShadow)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
final class ListViewReorderingItemNode: ASDisplayNode {
weak var itemNode: ListViewItemNode?
var currentState: (Int, Int)?
private let copyView: CopyView
private let initialLocation: CGPoint
init(itemNode: ListViewItemNode, initialLocation: CGPoint, hasShadow: Bool) {
self.itemNode = itemNode
self.copyView = CopyView(frame: CGRect(), hasShadow: hasShadow)
let snapshotView = itemNode.snapshotForReordering()
self.initialLocation = initialLocation
super.init()
if let snapshotView = snapshotView {
snapshotView.frame = CGRect(origin: CGPoint(), size: itemNode.bounds.size)
snapshotView.bounds.origin = itemNode.bounds.origin
self.copyView.addSubview(snapshotView)
}
self.view.addSubview(self.copyView)
self.copyView.frame = CGRect(origin: CGPoint(x: initialLocation.x, y: initialLocation.y), size: itemNode.bounds.size)
self.copyView.topShadow.frame = CGRect(origin: CGPoint(x: 0.0, y: -30.0), size: CGSize(width: copyView.bounds.size.width, height: 45.0))
self.copyView.bottomShadow.frame = CGRect(origin: CGPoint(x: 0.0, y: self.copyView.bounds.size.height - 15.0), size: CGSize(width: self.copyView.bounds.size.width, height: 45.0))
self.copyView.topShadow.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.25)
self.copyView.bottomShadow.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.25)
}
func updateOffset(offset: CGFloat) {
self.copyView.frame = CGRect(origin: CGPoint(x: initialLocation.x, y: initialLocation.y + offset), size: copyView.bounds.size)
}
func currentOffset() -> CGFloat? {
return self.copyView.center.y
}
func animateCompletion(completion: @escaping () -> Void) {
if let itemNode = self.itemNode {
let offset = itemNode.frame.midY - copyView.frame.midY
itemNode.isHidden = false
self.copyView.isHidden = true
itemNode.transitionOffset = offset
itemNode.addTransitionOffsetAnimation(0.0, duration: 0.3 * UIView.animationDurationFactor(), beginAt: CACurrentMediaTime())
completion()
/*itemNode.transitionOffset = 0.0
itemNode.setAnimationForKey("transitionOffset", animation: nil)
self.copyView.topShadow.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2)
self.copyView.bottomShadow.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2)
self.copyView.layer.animatePosition(from: CGPoint(), to: CGPoint(x: 0.0, y: itemNode.frame.midY - copyView.frame.midY), duration: 0.2, removeOnCompletion: false, additive: true, force: true, completion: { [weak itemNode] _ in
itemNode?.isHidden = false
completion()
})*/
} else {
completion()
}
}
}