SwiftMessages icon indicating copy to clipboard operation
SwiftMessages copied to clipboard

Knowing when an hide operation is completed

Open giofid opened this issue 4 years ago • 4 comments

Hi @wtmoose, In my app, I'm using SwiftMessages to show an activity-indicator view during a time consuming operation. All it's ok. I found the indefinite(delay: TimeInterval, minimum: TimeInterval) enum case very useful. Now, when my time consuming operation is over (a network request for example), I have to push a new view controller. If I set the delay property to 1s and the minimum property to 1s, and my operation finishes in 1.5 seconds, I will still see the activity-indicator view for about 0.5 seconds after the push. In my opinion, to solve this, it would be useful to know when an hide operation is effectively completed to do the push only then. Something like:

open func hide(id: String, completion: (() -> Void)? = nil)

What do you think of this?

giofid avatar Sep 18 '20 10:09 giofid

Have you looked at SwiftMessages.Config.eventListeners?

wtmoose avatar Sep 18 '20 12:09 wtmoose

Sorry, I should have looked harder!!

However, I think SwiftMessages.Config.eventListeners is not suitable in my use case. eventListeners property has to be set when I show the activity-indicator view, but I will know what to do only after the time consuming operation is completed. For example, a network request could be finish successfully or with an error. In the former case I have to push a new view controller; in the latter one I have to present an alert.

giofid avatar Sep 18 '20 12:09 giofid

Thinking about this...

wtmoose avatar Sep 20 '20 16:09 wtmoose

Hi @wtmoose, Meanwhile, I solved with this workaround

final class HUD {
    
    static let shared = HUD()
    
    private let swiftMessages = SwiftMessages()
    
    private var didHideHandler: (() -> ())?
    
    private lazy var activityIndicatorView: ActivityIndicatorView = {
        let activityIndicatorView: ActivityIndicatorView = try! SwiftMessages.viewFromNib()
        activityIndicatorView.id = "ActivityIndicatorView"
        return activityIndicatorView
    }()
    
    private lazy var activityIndicatorConfig: SwiftMessages.Config = {
        var config = SwiftMessages.defaultConfig
        config.presentationContext = .window(windowLevel: UIWindow.Level.normal)
        config.presentationStyle = .center
        config.interactiveHide = false
        config.dimMode = .gray(interactive: false)
        config.eventListeners.append() { [weak self] event in
            if case .didHide = event {
                self?.didHideHandler?()
                self?.didHideHandler = nil
            }
        }
        return config
    }()
    
    func show(delay: TimeInterval = 0.5, minimum: TimeInterval = 2) {
        activityIndicatorConfig.duration = .indefinite(delay: delay, minimum: minimum)
        swiftMessages.show(config: activityIndicatorConfig, view: activityIndicatorView)
        swiftMessages.hide(id: messageView.id)
    }
    
    func hide(completion: (() -> Void)? = nil) {
        didHideHandler = completion
        swiftMessages.hideAll()
    }
}

I took advantage of the fact that closure behaves as a reference type.

However, as stated here, I don't know if it's a good idea to have a closure (eventListeners: [EventListener] closures' array in this case) in a struct (Config).

giofid avatar Sep 23 '20 08:09 giofid