Was ist ein Beispiel für das Laden von Overlays in Swift IOS-Anwendungen, wenn Sie lange Aufgaben ausführen? Beispiel zum Laden von Daten vom Remote-Server. Ich habe gegoogelt, aber keine Antwort gefunden.
Aktualisiert:
Danke für @Sebastian Dressler, das ist ein einfacher Weg. Ich habe meinen Code aktualisiert und er läuft cool
public class LoadingOverlay{
var overlayView = UIView()
var activityIndicator = UIActivityIndicatorView()
class var shared: LoadingOverlay {
struct Static {
static let instance: LoadingOverlay = LoadingOverlay()
}
return Static.instance
}
public func showOverlay(view: UIView) {
overlayView.frame = CGRectMake(0, 0, 80, 80)
overlayView.center = view.center
overlayView.backgroundColor = UIColor(hex: 0x444444, alpha: 0.7)
overlayView.clipsToBounds = true
overlayView.layer.cornerRadius = 10
activityIndicator.frame = CGRectMake(0, 0, 40, 40)
activityIndicator.activityIndicatorViewStyle = .WhiteLarge
activityIndicator.center = CGPointMake(overlayView.bounds.width / 2, overlayView.bounds.height / 2)
overlayView.addSubview(activityIndicator)
view.addSubview(overlayView)
activityIndicator.startAnimating()
}
public func hideOverlayView() {
activityIndicator.stopAnimating()
overlayView.removeFromSuperview()
}
}
Lassen Sie mit:
LoadingOverlay.shared.showOverlay(self.view)
//To to long tasks
LoadingOverlay.shared.hideOverlayView()
Antworten:
Die obigen Antworten fügen eine Ladeansicht hinzu, blockieren jedoch keine Klickereignisse auf dem Bildschirm und bieten keine Überlagerung für den Rest des Bildschirms. Sie können dies wie folgt erreichen:
let alert = UIAlertController(title: nil, message: "Please wait...", preferredStyle: .Alert) alert.view.tintColor = UIColor.blackColor() let loadingIndicator: UIActivityIndicatorView = UIActivityIndicatorView(frame: CGRectMake(10, 5, 50, 50)) as UIActivityIndicatorView loadingIndicator.hidesWhenStopped = true loadingIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.Gray loadingIndicator.startAnimating(); alert.view.addSubview(loadingIndicator) presentViewController(alert, animated: true, completion: nil)
Swift 3.0
let alert = UIAlertController(title: nil, message: "Please wait...", preferredStyle: .alert) let loadingIndicator = UIActivityIndicatorView(frame: CGRect(x: 10, y: 5, width: 50, height: 50)) loadingIndicator.hidesWhenStopped = true loadingIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.gray loadingIndicator.startAnimating(); alert.view.addSubview(loadingIndicator) present(alert, animated: true, completion: nil)
Swift 4.0 und neuer
let alert = UIAlertController(title: nil, message: "Please wait...", preferredStyle: .alert) let loadingIndicator = UIActivityIndicatorView(frame: CGRect(x: 10, y: 5, width: 50, height: 50)) loadingIndicator.hidesWhenStopped = true loadingIndicator.style = UIActivityIndicatorView.Style.gray loadingIndicator.startAnimating(); alert.view.addSubview(loadingIndicator) present(alert, animated: true, completion: nil)
und Sie können es wie folgt verstecken:
dismiss(animated: false, completion: nil)
Es wird wie folgt gezeigt:
quelle
internal func dismissAlert() { if let vc = self.presentedViewController, vc is UIAlertController { dismiss(animated: false, completion: nil) } }
Warning: Attempt to present <UIAlertController: 0x7fc4f106e600> on <MyProj.MyViewController: 0x7fc4f3222710> whose view is not in the window hierarchy!
**navigationController?.pushViewController(adminHomeVC, animated: true)**
funktioniert nicht .. (schnell 4)loadingIndicator.style
anloadingIndicator.activityIndicatorViewStyle
in Swift 4Erstellen Sie einfach eine Überlagerungsansicht, die Sie Ihrer übergeordneten Ansicht hinzufügen, und entfernen Sie sie, sobald Ihre Aufgabe erledigt ist, z. B. um sie hinzuzufügen:
var overlay : UIView? // This should be a class variable [ ... ] overlay = UIView(frame: view.frame) overlay!.backgroundColor = UIColor.blackColor() overlay!.alpha = 0.8 view.addSubview(overlay!)
Zum Entfernen:
quelle
!
onoverlay...
Hintergrund verwischen + Aktivitätsanzeige, Beispiel Swift 5
extension UIView { func showBlurLoader() { let blurLoader = BlurLoader(frame: frame) self.addSubview(blurLoader) } func removeBluerLoader() { if let blurLoader = subviews.first(where: { $0 is BlurLoader }) { blurLoader.removeFromSuperview() } } } class BlurLoader: UIView { var blurEffectView: UIVisualEffectView? override init(frame: CGRect) { let blurEffect = UIBlurEffect(style: .dark) let blurEffectView = UIVisualEffectView(effect: blurEffect) blurEffectView.frame = frame blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight] self.blurEffectView = blurEffectView super.init(frame: frame) addSubview(blurEffectView) addLoader() } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } private func addLoader() { guard let blurEffectView = blurEffectView else { return } let activityIndicator = UIActivityIndicatorView(style: .whiteLarge) activityIndicator.frame = CGRect(x: 0, y: 0, width: 50, height: 50) blurEffectView.contentView.addSubview(activityIndicator) activityIndicator.center = blurEffectView.contentView.center activityIndicator.startAnimating() } }
quelle
Für alle, die spät dran sind wie ich, habe ich einige Änderungen am @ Sonrobby-Code vorgenommen. Soweit ich weiß, fügt @Sonrobby die Aktivität bei jedem
showOverlay
Anruf dem Overlay hinzu . Ein Teil der Konfiguration kann an die Init-Funktion übergeben werden, wobei nur die Platzierung auf dershowOverlay
Methode berücksichtigt wird.Ich ändere auch den Hintergrund des Overlays in Schwarz, da meine App meistens weiß ist.
Hier ist der Code:
public class LoadingOverlay{ var overlayView : UIView! var activityIndicator : UIActivityIndicatorView! class var shared: LoadingOverlay { struct Static { static let instance: LoadingOverlay = LoadingOverlay() } return Static.instance } init(){ self.overlayView = UIView() self.activityIndicator = UIActivityIndicatorView() overlayView.frame = CGRectMake(0, 0, 80, 80) overlayView.backgroundColor = UIColor(white: 0, alpha: 0.7) overlayView.clipsToBounds = true overlayView.layer.cornerRadius = 10 overlayView.layer.zPosition = 1 activityIndicator.frame = CGRectMake(0, 0, 40, 40) activityIndicator.center = CGPointMake(overlayView.bounds.width / 2, overlayView.bounds.height / 2) activityIndicator.activityIndicatorViewStyle = .WhiteLarge overlayView.addSubview(activityIndicator) } public func showOverlay(view: UIView) { overlayView.center = view.center view.addSubview(overlayView) activityIndicator.startAnimating() } public func hideOverlayView() { activityIndicator.stopAnimating() overlayView.removeFromSuperview() } }
quelle
Um die gegebenen Antworten zu ergänzen, können Probleme auftreten, wenn Sie manchmal versuchen, den Code auszuführen. Persönlich gab es eine Gelegenheit, in der showOverlay nicht richtig aufgerufen wurde (weil ich versuchte, in eine Szene überzugehen und diese Funktion dann sofort während viewDidLoad aufzurufen).
Wenn Sie auf ein ähnliches Problem wie ich stoßen, gibt es eine Korrektur für den Code und eine Änderung des Ansatzes, die ich empfehle.
UPDATE: Platzieren Sie beide Codeblöcke als Abschluss eines dispatch_async-Aufrufs wie folgt:
dispatch_async(dispatch_get_main_queue(), { //code });
ANSATZ: Wenn Sie Ihren Code aufrufen, führen Sie einen Aufruf von dispatch_after in der Hauptwarteschlange durch , um den Anruf um einige Millisekunden zu verzögern.
Die Begründung? Sie fordern die Benutzeroberfläche einfach auf, während viewDidLoad zu viel zu tun.
Wenn dieser Anhang zur Lösung helfen würde, wäre ich froh.
-Joel Long
PS Solution funktionierte für XCode v6.3.2
quelle
Verwenden Sie ATKit.
Siehe: https://aurvan.github.io/atkit-ios-release/index.html
ATProgressOverlay-Klasse https://aurvan.github.io/atkit-ios-release/helpbook/Classes/ATProgressOverlay.html
Code:
import ATKit ATProgressOverlay.sharedInstance.show() // Does not show network activity indicator on status bar. ATProgressOverlay.sharedInstance.show(isNetworkActivity: true) // Shows network activity indicator on status bar.
Bildschirmfoto:
quelle
Die @ sonrobby-Antwort wurde aktualisiert, eine Hintergrundansicht und eine Orientierungsbehandlung über die Größenänderungsmaske wurden hinzugefügt. Dies kann für einfache Dinge verwendet werden
public class LoadingOverlay{ var overlayView = UIView() var activityIndicator = UIActivityIndicatorView() var bgView = UIView() class var shared: LoadingOverlay { struct Static { static let instance: LoadingOverlay = LoadingOverlay() } return Static.instance } public func showOverlay(view: UIView) { bgView.frame = view.frame bgView.backgroundColor = UIColor.gray bgView.addSubview(overlayView) bgView.autoresizingMask = [.flexibleLeftMargin,.flexibleTopMargin,.flexibleRightMargin,.flexibleBottomMargin,.flexibleHeight, .flexibleWidth] overlayView.frame = CGRect(x: 0, y: 0, width: 80, height: 80) overlayView.center = view.center overlayView.autoresizingMask = [.flexibleLeftMargin,.flexibleTopMargin,.flexibleRightMargin,.flexibleBottomMargin] overlayView.backgroundColor = UIColor.black overlayView.clipsToBounds = true overlayView.layer.cornerRadius = 10 activityIndicator.frame = CGRect(x: 0, y: 0, width: 40, height: 40) activityIndicator.activityIndicatorViewStyle = .whiteLarge activityIndicator.center = CGPoint(x: overlayView.bounds.width / 2, y: overlayView.bounds.height / 2) overlayView.addSubview(activityIndicator) view.addSubview(bgView) self.activityIndicator.startAnimating() } public func hideOverlayView() { activityIndicator.stopAnimating() bgView.removeFromSuperview() } }
Wenn Sie es zum Tastenfenster hinzufügen, kann es auch über Ihre Navigations- und Registerkartenleisten gehen ... so etwas
LoadingOverlay.shared.showOverlay(view: UIApplication.shared.keyWindow!)
quelle
bgView.frame = view.bounds
? Daview.frame.origin
könnte sich von (0,0) unterscheiden.frame
Eigenschaft einer Ansicht immer im Koordinatensystem der übergeordneten Ansicht befindet. Wenn die Überlagerung die Ansicht, auf die sie angewendet wird, vollständig abdecken soll, müssen Sie sicherstellen, dass der Rahmen so groß ist wie die Zielansicht (übergeordnete Ansicht), aber auch bei (0,0) beginnt. ansonsten, wenn die übergeordnete Ansicht nicht am Ursprung ist ot seine übergeordnete Ansicht, so werden sich überlagern.Swift 3.
Ich habe @ Luchos Code in seiner Antwort unten verwendet und die Überlagerungshintergrundfarbe in klar geändert und eine Spinnerfarbe hinzugefügt.
public class LoadingOverlay { var overlayView : UIView! var activityIndicator : UIActivityIndicatorView! class var shared: LoadingOverlay { struct Static { static let instance: LoadingOverlay = LoadingOverlay() } return Static.instance } init(){ self.overlayView = UIView() self.activityIndicator = UIActivityIndicatorView() overlayView.frame = CGRect(0, 0, 80, 80) overlayView.backgroundColor = .clear overlayView.clipsToBounds = true overlayView.layer.cornerRadius = 10 overlayView.layer.zPosition = 1 activityIndicator.frame = CGRect(0, 0, 40, 40) activityIndicator.center = CGPoint(overlayView.bounds.width / 2, overlayView.bounds.height / 2) activityIndicator.activityIndicatorViewStyle = .whiteLarge activityIndicator.color = .gray overlayView.addSubview(activityIndicator) } public func showOverlay(view: UIView) { overlayView.center = view.center view.addSubview(overlayView) activityIndicator.startAnimating() } public func hideOverlayView() { activityIndicator.stopAnimating() overlayView.removeFromSuperview() } }
quelle
Ich habe ein Protokoll erstellt, um Ihren eigenen View Controller als Overlay darzustellen. Die Verwendung ist sehr einfach:
class ViewController: UIViewController, OverlayHost { @IBAction func showOverlayButtonPressed() { showOverlay(type: YourOverlayViewController.self, fromStoryboardWithName: "Main") } }
Ergebnis:
Quellcode: https://github.com/agordeev/OverlayViewController
In Verbindung stehender Artikel: https://andreygordeev.com/2017/04/18/overlay-view-controller-protocols-swift/
quelle
@ Ajinkya Patil Antwort als Referenz. Swift 4.0 und neuer
Dies ist eine Erweiterungslösung, die auf allen viewControllern ohne Konflikte verwendet werden kann.
Erstellen Sie einen LoadingDialog + ViewContoller.swift
import UIKit struct ProgressDialog { static var alert = UIAlertController() static var progressView = UIProgressView() static var progressPoint : Float = 0{ didSet{ if(progressPoint == 1){ ProgressDialog.alert.dismiss(animated: true, completion: nil) } } } } extension UIViewController{ func LoadingStart(){ ProgressDialog.alert = UIAlertController(title: nil, message: "Please wait...", preferredStyle: .alert) let loadingIndicator = UIActivityIndicatorView(frame: CGRect(x: 10, y: 5, width: 50, height: 50)) loadingIndicator.hidesWhenStopped = true loadingIndicator.style = UIActivityIndicatorView.Style.gray loadingIndicator.startAnimating(); ProgressDialog.alert.view.addSubview(loadingIndicator) present(ProgressDialog.alert, animated: true, completion: nil) } func LoadingStop(){ ProgressDialog.alert.dismiss(animated: true, completion: nil) } }
Rufen Sie die Funktion in ViewController an einer beliebigen Stelle auf. wie so:
self.LoadingStart()
und hier erfahren Sie, wie Sie den Ladedialog stoppen.
self.LoadingStop()
quelle
Swift 5
class func showUniversalLoadingView(_ show: Bool, loadingText : String = "") { let existingView = UIApplication.shared.windows[0].viewWithTag(1200) if show { if existingView != nil { return } let loadingView = self.makeLoadingView(withFrame: UIScreen.main.bounds, loadingText: loadingText) loadingView?.tag = 1200 UIApplication.shared.windows[0].addSubview(loadingView!) } else { existingView?.removeFromSuperview() } } class func makeLoadingView(withFrame frame: CGRect, loadingText text: String?) -> UIView? { let loadingView = UIView(frame: frame) loadingView.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.5) let activityIndicator = UIActivityIndicatorView(frame: CGRect(x: 0, y: 0, width: 100, height: 100)) //activityIndicator.backgroundColor = UIColor(red:0.16, green:0.17, blue:0.21, alpha:1) activityIndicator.layer.cornerRadius = 6 activityIndicator.center = loadingView.center activityIndicator.hidesWhenStopped = true activityIndicator.style = .white activityIndicator.startAnimating() activityIndicator.tag = 100 // 100 for example loadingView.addSubview(activityIndicator) if !text!.isEmpty { let lbl = UILabel(frame: CGRect(x: 0, y: 0, width: 200, height: 30)) let cpoint = CGPoint(x: activityIndicator.frame.origin.x + activityIndicator.frame.size.width / 2, y: activityIndicator.frame.origin.y + 80) lbl.center = cpoint lbl.textColor = UIColor.white lbl.textAlignment = .center lbl.text = text lbl.tag = 1234 loadingView.addSubview(lbl) } return loadingView }
Verwendet
showUniversalLoadingView(true, loadingText: "Downloading Data.......")
showUniversalLoadingView (true)
Lader entfernen
showUniversalLoadingView(false)
quelle