Skip to content

Commit

Permalink
Merge pull request #17 from bguidolim/rotate-animation
Browse files Browse the repository at this point in the history
Added way to enable rotation animation when expanding items
  • Loading branch information
pedrommcarrasco committed Jul 8, 2021
2 parents 5c9bb05 + 41c1c1e commit 4945ea1
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 7 deletions.
2 changes: 1 addition & 1 deletion Hover.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |spec|
spec.name = 'Hover'
spec.version = '1.4.0'
spec.version = '1.5.0'
spec.license = { :type => 'MIT', :file => 'LICENSE' }
spec.homepage = 'https://github.com/pedrommcarrasco/Hover'
spec.authors = { 'Pedro Carrasco' => 'https://twitter.com/pedrommcarrasco' }
Expand Down
12 changes: 12 additions & 0 deletions Hover/Model/HoverConfiguration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ public struct HoverConfiguration {
public var color: HoverColor
/// Image displayed in the floating button
public var image: UIImage?
/// Define the animation of the HoverButton's image when expding items
public var imageExpandAnimation: ImageExpandAnimation
/// Size of the floating button
public var size: CGFloat
/// Dictates the size of the image shown in any button (imageSize = size * imageSizeRatio)
Expand All @@ -47,6 +49,7 @@ public struct HoverConfiguration {

// MARK: Init
public init(image: UIImage? = nil,
imageExpandAnimation: ImageExpandAnimation = .none,
color: HoverColor = .color(.blue),
size: CGFloat = 60.0,
imageSizeRatio: CGFloat = 0.4,
Expand All @@ -58,6 +61,7 @@ public struct HoverConfiguration {

self.color = color
self.image = image
self.imageExpandAnimation = imageExpandAnimation
self.size = size
self.imageSizeRatio = imageSizeRatio
self.spacing = spacing
Expand All @@ -78,3 +82,11 @@ struct HoverItemConfiguration {
let initialXOrientation: Orientation.X
}

// MARK: - ImageExpandAnimation
public enum ImageExpandAnimation {
/// No animation
case none

/// Rotate considering the radian value. It considers the X and Y orientation when animating.
case rotate(_ radian: CGFloat)
}
4 changes: 2 additions & 2 deletions Hover/UI/HoverButton.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ class HoverButton: UIControl {
}

// MARK: Outlets
private var gradientLayer: CAGradientLayer?
private let imageView: UIImageView = .create {
let imageView: UIImageView = .create {
$0.contentMode = .scaleAspectFit
$0.isUserInteractionEnabled = false
}
private var gradientLayer: CAGradientLayer?
private let hightlightView: UIView = .create {
$0.backgroundColor = Constant.highlightColor
$0.isUserInteractionEnabled = false
Expand Down
33 changes: 29 additions & 4 deletions Hover/UI/HoverView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ public class HoverView: UIView {
static let interItemSpacing: CGFloat = 12.0
static let disabledAlpha: CGFloat = 0.75
static let disabledTransform = CGAffineTransform(scaleX: 0.9, y: 0.9)

}

// MARK: State
Expand Down Expand Up @@ -248,12 +247,14 @@ private extension HoverView {
}
}
}

private func animate(isOpening: Bool, anchor: Anchor, completion: (() -> Void)? = nil) {
itemsStackView.isUserInteractionEnabled = isOpening

UIViewPropertyAnimator(duration: Constant.animationDuration, curve: .easeInOut) {

let transform = imageExpandTransform(isOpening: isOpening)
UIViewPropertyAnimator(duration: Constant.animationDuration, dampingRatio: Constant.animationDamping) {
self.dimView.alpha = isOpening ? 1.0 : 0.0
self.button.imageView.transform = transform
}.startAnimation()

anchor.position.yOrientation.reverseArrayIfNeeded(itemsStackView.arrangedSubviews).enumerated().forEach { (index, view) in
Expand All @@ -274,6 +275,30 @@ private extension HoverView {
animator.startAnimation(afterDelay: Calculator.delay(for: index))
}
}

private func imageExpandTransform(isOpening: Bool) -> CGAffineTransform {
switch configuration.imageExpandAnimation {
case .none:
return .identity

case .rotate(let radianValue):
let factor: CGFloat

switch (currentAnchor.position.xOrientation, currentAnchor.position.yOrientation) {
case (.leftToRight, .bottomToTop),
(.rightToLeft, .topToBottom):
factor = 1
case (.leftToRight, .topToBottom),
(.rightToLeft, .bottomToTop):
factor = -1
}

let rotationValue: CGFloat = radianValue * factor
let rotationTransform = CGAffineTransform(rotationAngle: rotationValue)

return isOpening ? rotationTransform : .identity
}
}
}

// MARK: - Conditional Constraints
Expand Down

0 comments on commit 4945ea1

Please sign in to comment.