Was ist ein Beispiel für das Laden von Overlays in Swift IOS Anwendung bei langen Aufgaben. Beispiel für das Laden von Daten vom Remote-Server. Ich habe gegoogelt, aber keine Antwort gefunden.
Aktualisiert:
Danke für @Sebastian Dressler, das ist ganz einfach. Ich habe meinen Code aktualisiert und es 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 mit:
LoadingOverlay.shared.showOverlay(self.view)
//To to long tasks
LoadingOverlay.shared.hideOverlayView()
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 es 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 ausblenden:
dismiss(animated: false, completion: nil)
Erstellen Sie einfach eine Überlagerungsansicht, die Sie zu Ihrer übergeordneten Ansicht hinzufügen, und entfernen Sie sie, wenn Ihre Aufgabe erledigt ist, z. um es 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:
overlay?.removeFromSuperview()
Hintergrundunschärfe + Aktivitätsanzeige, Swift 5 Beispiel
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()
}
}
Für jemanden wie mich habe ich einige Änderungen am @ Sonrobby-Code vorgenommen. Nach meinem Verständnis fügt @Sonrobby die Aktivität bei jedem showOverlay
-Aufruf zum Overlay hinzu. Ein Teil der Konfiguration kann an die init-Funktion übergeben werden, sodass nur die Platzierung in der showOverlay
-Methode zulässig ist.
Ich ändere auch den Hintergrund der Überlagerung in Schwarz, da meine App überwiegend 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()
}
}
Wenn Sie versuchen, den Code manchmal auszuführen, können Probleme auftreten, um die angegebenen Antworten zu ergänzen. Persönlich gab es eine Gelegenheit, in der showOverlay nicht richtig aufgerufen wurde (weil ich versuchte, in eine Szene zu springen und diese Funktion dann sofort während viewDidLoad aufzurufen).
Wenn Sie auf ein ähnliches Problem stoßen wie ich, gibt es eine Korrektur des Codes und eine Änderung der Vorgehensweise, die ich empfehle.
UPDATE: Platzieren Sie beide Codeblöcke wie folgt als Abschlüsse für einen dispatch_async-Aufruf:
dispatch_async(dispatch_get_main_queue(),
{ //code });
Vorgehensweise: Wenn Sie Ihren Code aufrufen, führen Sie einen dispatch_after-Aufruf in der Hauptwarteschlange aus, um den Anruf um einige Millisekunden zu verzögern.
Die Begründung? Sie bitten die Benutzeroberfläche lediglich, während viewDidLoad zu viel zu tun.
Wenn dieser Anhang zur Lösung geholfen hat, würde ich mich freuen.
-Joel Long
P.S. Die Lösung funktionierte für XCode v6.3.2
@Sonrobby answer aktualisiert, Hintergrundansicht und Orientierungshilfe über die Größenänderungsmaske 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 zu keywindow hinzufügen, kann es auch über die Navigations- und Tab-Leisten gehen ... in etwa so
LoadingOverlay.shared.showOverlay(view: UIApplication.shared.keyWindow!)
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:
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
Passender Artikel: https://andreygordeev.com/2017/04/18/overlay-view-controller-protocols-Swift/
Schnell 3.
Ich habe @ Luchos Code in seiner Antwort unten verwendet und die Hintergrundfarbe der Überlagerung geändert, um sie zu löschen und eine Spinnerfarbe hinzuzufügen.
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()
}
}