Last active
December 17, 2023 13:37
-
-
Save edc0der/e4bed05b4c6653ffcd36c0609f27c7c6 to your computer and use it in GitHub Desktop.
iOS + Swift: Display activity indicator overlay - UIViewController extension
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
fileprivate let overlayViewTag: Int = 999 | |
fileprivate let activityIndicatorViewTag: Int = 1000 | |
// Public interface | |
extension UIView { | |
func displayAnimatedActivityIndicatorView() { | |
setActivityIndicatorView() | |
} | |
func hideAnimatedActivityIndicatorView() { | |
removeActivityIndicatorView() | |
} | |
} | |
extension UIViewController { | |
private var overlayContainerView: UIView { | |
if let navigationView: UIView = navigationController?.view { | |
return navigationView | |
} | |
return view | |
} | |
func displayAnimatedActivityIndicatorView() { | |
overlayContainerView.displayAnimatedActivityIndicatorView() | |
} | |
func hideAnimatedActivityIndicatorView() { | |
overlayContainerView.hideAnimatedActivityIndicatorView() | |
} | |
} | |
// Private interface | |
extension UIView { | |
private var activityIndicatorView: UIActivityIndicatorView { | |
let view: UIActivityIndicatorView = UIActivityIndicatorView(style: .large) | |
view.translatesAutoresizingMaskIntoConstraints = false | |
view.tag = activityIndicatorViewTag | |
return view | |
} | |
private var overlayView: UIView { | |
let view: UIView = UIView() | |
view.translatesAutoresizingMaskIntoConstraints = false | |
view.backgroundColor = .black | |
view.alpha = 0.5 | |
view.tag = overlayViewTag | |
return view | |
} | |
private func setActivityIndicatorView() { | |
guard !isDisplayingActivityIndicatorOverlay() else { return } | |
let overlayView: UIView = self.overlayView | |
let activityIndicatorView: UIActivityIndicatorView = self.activityIndicatorView | |
//add subviews | |
overlayView.addSubview(activityIndicatorView) | |
addSubview(overlayView) | |
//add overlay constraints | |
overlayView.heightAnchor.constraint(equalTo: heightAnchor).isActive = true | |
overlayView.widthAnchor.constraint(equalTo: widthAnchor).isActive = true | |
//add indicator constraints | |
activityIndicatorView.centerXAnchor.constraint(equalTo: overlayView.centerXAnchor).isActive = true | |
activityIndicatorView.centerYAnchor.constraint(equalTo: overlayView.centerYAnchor).isActive = true | |
//animate indicator | |
activityIndicatorView.startAnimating() | |
} | |
private func removeActivityIndicatorView() { | |
guard let overlayView: UIView = getOverlayView(), let activityIndicator: UIActivityIndicatorView = getActivityIndicatorView() else { | |
return | |
} | |
UIView.animate(withDuration: 0.2, animations: { | |
overlayView.alpha = 0.0 | |
activityIndicator.stopAnimating() | |
}) { _ in | |
activityIndicator.removeFromSuperview() | |
overlayView.removeFromSuperview() | |
} | |
} | |
private func isDisplayingActivityIndicatorOverlay() -> Bool { | |
getActivityIndicatorView() != nil && getOverlayView() != nil | |
} | |
private func getActivityIndicatorView() -> UIActivityIndicatorView? { | |
viewWithTag(activityIndicatorViewTag) as? UIActivityIndicatorView | |
} | |
private func getOverlayView() -> UIView? { | |
viewWithTag(overlayViewTag) | |
} | |
} |
Cheers!
β¦On Fri, 29 May 2020 at 9:26 PM, Eduard Moya ***@***.***> wrote:
***@***.**** commented on this gist.
------------------------------
Updated the snippet with @acamill's <https://gist.github.com/acamill>
suggested code. Thank you!
Changes:
- Added type annotation
- Separated the display method into display and hide, in order to have
single responsibility methods
- Added UIViewController extension to use the overlay to cover the
fullscreen without having to write
navigationController?.view.displayAnimatedActivityIndicatorView()
β
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<https://gist.github.com/e4bed05b4c6653ffcd36c0609f27c7c6#gistcomment-3322674>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AJTOZY7BLLMUXOSUJPUXYJDRT6ZZBANCNFSM4JRGSANA>
.
How is this applied to a normal swiftUI page. If I want the page to display the loading icon how do I do that?
Import SwiftUI
struct Welcome: View {
var body: some View {
<< DISPLAY LOADING HERE >>
Text("Hello World")
}
}
struct Dashboard_Previews: PreviewProvider {
static var previews: some View {
Welcome()
}
}
Thanks for sharing!
πββοΈ
β¦On Thu, 6 Aug 2020 at 11:45 AM, ahmdmau ***@***.***> wrote:
***@***.**** commented on this gist.
------------------------------
Thanks for sharing!
β
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<https://gist.github.com/e4bed05b4c6653ffcd36c0609f27c7c6#gistcomment-3406425>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AJTOZY6GEGBSYFR4MLI2PDDR7IRO5ANCNFSM4JRGSANA>
.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Updated the snippet with @acamill's suggested code. Thank you!
Changes:
navigationController?.view.displayAnimatedActivityIndicatorView()