         return label
     }()
 
-    private var state: State = .hidden
-    private let startAnimatingGroup = DispatchGroup()
+    fileprivate var state: State = .stopped
+    fileprivate var data: ActivityData? // Shared activity data across states
+
+    /// The group to synchronize the message so that the one set by `setMessage` is always displayed after the initial message passed to `startAnimating(_:)`.
+    fileprivate let waitingToStartGroup = DispatchGroup()
 
     /// Shared instance of `NVActivityIndicatorPresenter`.
     public static let sharedInstance = NVActivityIndicatorPresenter()


            keyWindow.addConstraints([leadingConstraint, trailingConstraint, topConstraint, bottomConstraint])
        }())

        DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(activityData.minimumDisplayTime)) {
            self._hide()
        }
    }

    private func _hide() {
        if state == .waitingToHide {
            hide()
        } else if state == .waitingToShow {
            state = .hidden
        } else if state != .hidden {
            state = .waitingToHide
        }
    }

    private func hide() {
        guard let keyWindow = UIApplication.shared.keyWindow else { return }

        for item in keyWindow.subviews
            where item.restorationIdentifier == restorationIdentifier {
            item.removeFromSuperview()
        }
        state = .hidden
    }
}

        guard let keyWindow = UIApplication.shared.keyWindow else { return }

        keyWindow.addSubview(containerView)

        // Add constraints for `containerView`.
        ({
