Closed yunustek closed 3 years ago
No reason in particular. I'll add options if there's a need for it. Can you not just call hide()
in the completion block of your other animations?
No reply. Closing
I can't pause the hide process when I define auto hide time. I can hide but i can't pause hiding. I think you need add delay
option to hide like this:
Using:
let animator = TopBottomAnimation(style: .top)
animator.hideDelay = 2
config.presentationStyle = .custom(animator: animator)
Changes: hideDelay
func hide(context: AnimationContext, completion: @escaping AnimationCompletion) {
NotificationCenter.default.removeObserver(self)
let view = context.messageView
self.context = context
UIView.animate(withDuration: hideDuration, delay: hideDelay, options: [.beginFromCurrentState, .curveEaseIn], animations: {
switch self.style {
case .top:
view.transform = CGAffineTransform(translationX: 0, y: -view.frame.height)
case .bottom:
view.transform = CGAffineTransform(translationX: 0, y: view.frame.maxY + view.frame.height)
}
}, completion: { completed in
completion(completed || UIApplication.shared.applicationState != .active)
})
}
It isn't quite as straightforward as adding a hideDelay
property. The animator is required to provide an accurate value for hideDuration
, which is a read/write property on TopBottomAnimation
but it also needs to include hideDelay
. I'd need to make an API change to accomplish this.
Regardless, my recommendation is to make your own animator and use composition with TopBottomAnimation
. Something like this, nice and self-contained:
class FancyAnimation: Animator {
var delegate: AnimationDelegate? {
get {
return animation.delegate
}
set {
animation.delegate = newValue
}
}
func show(context: AnimationContext, completion: @escaping AnimationCompletion) {
animation.show(context: context, completion: completion)
}
func hide(context: AnimationContext, completion: @escaping AnimationCompletion) {
UIView.animate(withDuration: localHideDuration, delay: 0, options: [.beginFromCurrentState, .curveEaseIn]) {
let view = context.messageView
view.alpha = 0.5
} completion: { _ in
self.animation.hide(context: context, completion: completion)
}
}
var showDuration: TimeInterval { return animation.showDuration }
var hideDuration: TimeInterval { return animation.hideDuration + localHideDuration }
init(animation: Animator) {
self.animation = animation
}
private let localHideDuration: TimeInterval = 1
private let animation: Animator
}
Then you can do something like this:
let topBottomAnimation = TopBottomAnimation(style: .top)
let animation = FancyAnimation(animation: topBottomAnimation)
var config = SwiftMessages.defaultConfig
config.presentationStyle = .custom(animator: animation)
Okay I try it but it's not hiding when I swiping to top?
Oh yeah, I forgot to test the interactive hide.
Here's an update, which is more complicated than I'd like, but you can use it as a workaround while I try to think of something better.
class FancyAnimation: Animator {
var delegate: AnimationDelegate?
func show(context: AnimationContext, completion: @escaping AnimationCompletion) {
animation.show(context: context, completion: completion)
}
func hide(context: AnimationContext, completion: @escaping AnimationCompletion) {
if doLocalHide {
UIView.animate(withDuration: localHideDuration, delay: 0, options: [.beginFromCurrentState, .curveEaseIn]) {
let view = context.messageView
view.alpha = 0.5
} completion: { _ in
self.animation.hide(context: context, completion: completion)
}
} else {
self.animation.hide(context: context, completion: completion)
}
}
var showDuration: TimeInterval { return animation.showDuration }
var hideDuration: TimeInterval {
return animation.hideDuration + (doLocalHide ? localHideDuration : 0)
}
init(animation: Animator) {
self.animation = animation
animation.delegate = self
}
private var doLocalHide = true
private let localHideDuration: TimeInterval = 1
private let animation: Animator
}
extension FancyAnimation: AnimationDelegate {
func hide(animator: Animator) {
doLocalHide = false
delegate?.hide(animator: self)
}
func panStarted(animator: Animator) {
delegate?.panStarted(animator: self)
}
func panEnded(animator: Animator) {
delegate?.panEnded(animator: self)
}
}
Why didn't you give a delay option to the hide animation? I want to run an animation on the popup before I start hiding, and the shutdown process shouldn't start until that animation time is over.