SwiftKickMobile / SwiftMessages

A very flexible message bar for UIKit and SwiftUI.
MIT License
7.3k stars 742 forks source link

Control animation speed #365

Closed foxware00 closed 4 years ago

foxware00 commented 4 years ago

Is there a simple way to control the animation speed. I can extend the Animator and copy it over and change the value, but in doing so I lose the Presenter logic which looks for .bottom. Now I need to copy over vast quantities of code just to make the hide animation the same length as the show.

Is there a simple way to a simple change the animation duration?

wtmoose commented 4 years ago

I need to introduce a protocol so that any animator can prefer to be installed under navigation and tab bars.

foxware00 commented 4 years ago

Is there a simple way to surface show/hide animation speed similar to pauseBetweenMessages

wtmoose commented 4 years ago

You can set the hide and show durations on TopBottomAnimation, but you’d have to use .custom presentation style and, as you said, you’d lose the Presenter logic.

The only current workaround I can think of is to use .custom as described above and use presentationStyle = .view, where you supply a container view that duplicates where Presenter is installing the MaskingView for presentationStyle = .bottom (line 334 of Presenter.

foxware00 commented 4 years ago

I've tried both of these, but I share the message across multiple view controllers so the animation replays or doesn't show at all each time I change tab. When I set the view controller everything works perfectly except the animations are too short.

wtmoose commented 4 years ago

Then I don’t have a workaround for you. My intention is to add the protocol, which will solve your problem, as soon as I can get to it.

foxware00 commented 4 years ago

Okay, thanks @wtmoose I look forward to it. In the meantime, I've forked the repo and made TopBottomAnimation.swift open instead of public and modified the install() function inside Presenter.swift


func topLayoutConstraint(view: UIView, containerView: UIView, viewController: UIViewController?) -> NSLayoutConstraint {
    if case .top = config.presentationStyle.topBottomStyle, let nav = viewController as? UINavigationController, nav.sm_isVisible(view: nav.navigationBar) {
        return NSLayoutConstraint(item: view, attribute: .top, relatedBy: .equal, toItem: nav.navigationBar, attribute: .bottom, multiplier: 1.00, constant: 0.0)
    }
    return NSLayoutConstraint(item: view, attribute: .top, relatedBy: .equal, toItem: containerView, attribute: .top, multiplier: 1.00, constant: 0.0)
}

func bottomLayoutConstraint(view: UIView, containerView: UIView, viewController: UIViewController?) -> NSLayoutConstraint {
    if case .bottom = config.presentationStyle.topBottomStyle, let tab = viewController as? UITabBarController, tab.sm_isVisible(view: tab.tabBar) {
        return NSLayoutConstraint(item: view, attribute: .bottom, relatedBy: .equal, toItem: tab.tabBar, attribute: .top, multiplier: 1.00, constant: 0.0)
    }
    return NSLayoutConstraint(item: view, attribute: .bottom, relatedBy: .equal, toItem: containerView, attribute: .bottom, multiplier: 1.00, constant: 0.0)
}
wtmoose commented 4 years ago

What’s the purpose of making TopBottomAnimation open? I’m not necessarily opposed, but for this class, my thought was it makes more sense to add configuration options as new use cases come up.

foxware00 commented 4 years ago

Because the classes internally check whether the custom class is as? TopBottomAnimation and cast to .top or .bottom So when using .viewController() I wasn't getting the same behavior with .view. Given I just wanted to override and change the hideDuration this seemed like the simplest solution to stop-gap an official one.

wtmoose commented 4 years ago

I fixed this on the head of master. It was really just a bug in Presenter.swift. Can you try it out and let me know if it works for you?

I made showDuration and hideDuration writable, so you can do something like this without subclassing:

let message: MessageView = MessageView.viewFromNib(layout: .cardView)
var config = SwiftMessages.defaultConfig
let animator = TopBottomAnimation(style: .bottom)
animator.showDuration = 3
animator.hideDuration = 1
config.presentationStyle = .custom(animator: animator)
SwiftMessages.show(config: config, view: message)
gharibi commented 4 years ago

hey @wtmoose. I just checked this with v7.0.1 and I get the below error:

Cannot assign to property: 'showDuration' is a get-only property

Are you sure that your changes are merged in master branch? 🤔

wtmoose commented 4 years ago

@gharibi 7.0.1 is not head of master

gharibi commented 4 years ago

@wtmoose I checked the master branch and your solution seem to work fine. When are you planning to include these changes in a release?

wtmoose commented 4 years ago

Included in 8.0.0 release