Initial implementation of attachment menu

This commit is contained in:
Ilya Laktyushin
2022-02-11 19:38:28 +03:00
parent 8bd663e908
commit 7da0357b6d
45 changed files with 3105 additions and 191 deletions

View File

@@ -67,8 +67,14 @@ public extension Transition.DisappearWithGuide {
public extension Transition.Update {
static let `default` = Transition.Update { component, view, transition in
let frame = component.size.centered(around: component._position ?? CGPoint())
if view.frame != frame {
transition.setFrame(view: view, frame: frame)
if let scale = component._scale {
transition.setBounds(view: view, bounds: CGRect(origin: CGPoint(), size: frame.size))
transition.setPosition(view: view, position: frame.center)
transition.setScale(view: view, scale: scale)
} else {
if view.frame != frame {
transition.setFrame(view: view, frame: frame)
}
}
let opacity = component._opacity ?? 1.0
if view.alpha != opacity {

View File

@@ -175,6 +175,7 @@ public final class _UpdatedChildComponent {
var _removed: Bool = false
var _position: CGPoint?
var _scale: CGFloat?
var _opacity: CGFloat?
var _cornerRadius: CGFloat?
var _clipsToBounds: Bool?
@@ -239,6 +240,11 @@ public final class _UpdatedChildComponent {
return self
}
@discardableResult public func scale(_ scale: CGFloat) -> _UpdatedChildComponent {
self._scale = scale
return self
}
@discardableResult public func opacity(_ opacity: CGFloat) -> _UpdatedChildComponent {
self._opacity = opacity
return self
@@ -683,7 +689,13 @@ public extension CombinedComponent {
view.insertSubview(updatedChild.view, at: index)
updatedChild.view.frame = updatedChild.size.centered(around: updatedChild._position ?? CGPoint())
if let scale = updatedChild._scale {
updatedChild.view.bounds = CGRect(origin: CGPoint(), size: updatedChild.size)
updatedChild.view.center = updatedChild._position ?? CGPoint()
updatedChild.view.transform = CGAffineTransform(scaleX: scale, y: scale)
} else {
updatedChild.view.frame = updatedChild.size.centered(around: updatedChild._position ?? CGPoint())
}
updatedChild.view.alpha = updatedChild._opacity ?? 1.0
updatedChild.view.clipsToBounds = updatedChild._clipsToBounds ?? false
updatedChild.view.layer.cornerRadius = updatedChild._cornerRadius ?? 0.0

View File

@@ -176,6 +176,40 @@ public struct Transition {
}
}
public func setBounds(view: UIView, bounds: CGRect, completion: ((Bool) -> Void)? = nil) {
if view.bounds == bounds {
completion?(true)
return
}
switch self.animation {
case .none:
view.bounds = bounds
completion?(true)
case .curve:
let previousBounds = view.bounds
view.bounds = bounds
self.animateBounds(view: view, from: previousBounds, to: view.bounds, completion: completion)
}
}
public func setPosition(view: UIView, position: CGPoint, completion: ((Bool) -> Void)? = nil) {
if view.center == position {
completion?(true)
return
}
switch self.animation {
case .none:
view.center = position
completion?(true)
case .curve:
let previousPosition = view.center
view.center = position
self.animatePosition(view: view, from: previousPosition, to: view.center, completion: completion)
}
}
public func setAlpha(view: UIView, alpha: CGFloat, completion: ((Bool) -> Void)? = nil) {
if view.alpha == alpha {
completion?(true)
@@ -191,7 +225,35 @@ public struct Transition {
self.animateAlpha(view: view, from: previousAlpha, to: alpha, completion: completion)
}
}
public func setScale(view: UIView, scale: CGFloat, completion: ((Bool) -> Void)? = nil) {
let t = view.layer.presentation()?.transform ?? view.layer.transform
let currentScale = sqrt((t.m11 * t.m11) + (t.m12 * t.m12) + (t.m13 * t.m13))
if currentScale == scale {
completion?(true)
return
}
switch self.animation {
case .none:
view.layer.transform = CATransform3DMakeScale(scale, scale, 1.0)
completion?(true)
case let .curve(duration, curve):
let previousScale = currentScale
view.layer.transform = CATransform3DMakeScale(scale, scale, 1.0)
view.layer.animate(
from: previousScale as NSNumber,
to: scale as NSNumber,
keyPath: "transform.scale",
duration: duration,
delay: 0.0,
curve: curve,
removeOnCompletion: true,
additive: false,
completion: completion
)
}
}
public func setSublayerTransform(view: UIView, transform: CATransform3D, completion: ((Bool) -> Void)? = nil) {
switch self.animation {
case .none: