custom activity ios uitableview swift uiactivityindicatorview

ios - custom - activity indicator swift 4



¿Cómo mostrar el indicador de actividad mientras se carga tableView? (10)

Cuando cambio entre mis pestañas, se cargan algunos segundos y quiero saber que mis datos se están cargando. Para eso decidí agregar un indicador de actividad.

Escribí una pequeña función:

func showActivityIndicator() { dispatch_async(dispatch_get_main_queue()) { self.spinner = UIActivityIndicatorView(activityIndicatorStyle: .WhiteLarge) self.spinner.frame = CGRect(x: 0.0, y: 0.0, width: 80.0, height: 80.0) self.spinner.center = CGPoint(x:self.loadingView.bounds.size.width / 2, y:self.loadingView.bounds.size.height / 2) self.loadingView.addSubview(self.spinner) self.view.addSubview(self.loadingView) self.spinner.startAnimating() } }

Eso mostrará mi indicador. Y trate de usarlo cuando pulsé desde mi infoController al botón:

@IBAction func goToMainFromInfo(sender: AnyObject) { self.showActivityIndicator() self.performSegueWithIdentifier("fromMainToInfoWActivity", sender: nil) self.hideActivityIndicator() } }

Lo muestro antes de segue realizar y ocultar después. No me ayuda Cuando intenté usar la sincronización:

@IBAction func goToMainFromInfo(sender: AnyObject) { dispatch_async(dispatch_get_main_queue()) { self.showActivityIndicator() self.performSegueWithIdentifier("fromMainToInfoWActivity", sender: nil) self.hideActivityIndicator() } }

Pero tampoco ayuda. Cuando presiono para tabular, la opacidad se convierte en 0.5 y espero mientras se carga. Pero no veo mi indicador de actividad.

¿Cuál es el problema?


Este código puede ayudarte :)

let indicator:UIActivityIndicatorView = UIActivityIndicatorView (activityIndicatorStyle: UIActivityIndicatorViewStyle.Gray) indicator.color = UIColor .magentaColor() indicator.frame = CGRectMake(0.0, 0.0, 10.0, 10.0) indicator.center = self.view.center self.view.addSubview(indicator) indicator.bringSubviewToFront(self.view) indicator.startAnimating()


La respuesta de @ brocolli para swift 4.0. Debe usar objc_ antes de obtener o configurar objetos asociados. Según la documentación, las API de obtención y configuración del objeto asociado en Swift son:

func objc_getAssociatedObject(object: AnyObject!, key: UnsafePointer<Void> ) -> AnyObject! func objc_setAssociatedObject(object: AnyObject!, key: UnsafePointer<Void>, value: AnyObject!, policy: objc_AssociationPolicy)

Implementación:

import UIKit fileprivate var ActivityIndicatorViewAssociativeKey = "ActivityIndicatorViewAssociativeKey" extension UIView { var activityIndicatorView: UIActivityIndicatorView { get { if let activityIndicatorView = objc_getAssociatedObject(self, &ActivityIndicatorViewAssociativeKey) as? UIActivityIndicatorView { return activityIndicatorView } else { let activityIndicatorView = UIActivityIndicatorView(frame: CGRect(x: 0, y: 0, width: 40, height: 40)) activityIndicatorView.activityIndicatorViewStyle = .gray activityIndicatorView.color = .gray activityIndicatorView.center = center activityIndicatorView.hidesWhenStopped = true addSubview(activityIndicatorView) objc_setAssociatedObject(self, &ActivityIndicatorViewAssociativeKey, activityIndicatorView, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) return activityIndicatorView } } set { addSubview(newValue) objc_setAssociatedObject(self, &ActivityIndicatorViewAssociativeKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) } } }


Otro enfoque, en mi código, agregué una extensión para UITableView (Swift 2.3):

extension UITableView { func activityIndicator(center: CGPoint = CGPointZero, loadingInProgress: Bool) { let tag = 12093 if loadingInProgress { var indicator = UIActivityIndicatorView() indicator = UIActivityIndicatorView(frame: CGRectMake(0, 0, 40, 40)) indicator.tag = tag indicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.WhiteLarge indicator.color = //Your color here indicator.center = center indicator.startAnimating() indicator.hidesWhenStopped = true self.superview?.addSubview(indicator) }else { if let indicator = self.superview?.viewWithTag(tag) as? UIActivityIndicatorView { { indicator.stopAnimating() indicator.removeFromSuperview() } } } }

Nota: Mi vista de tabla está incrustada en una vista UIV (supervisión)


Para colocar el UIActivityIndicator en primer plano, incluso sobre los eventuales separadores UITableViewController, he adoptado esta solución.

  • He agregado el UIActivityIndicator programáticamente, y lo agrego como una subvista de mi UINavigationController

    func objc_getAssociatedObject(object: AnyObject!, key: UnsafePointer<Void> ) -> AnyObject! func objc_setAssociatedObject(object: AnyObject!, key: UnsafePointer<Void>, value: AnyObject!, policy: objc_AssociationPolicy)

  • Acabo de iniciarlo y detenerlo cuando sea necesario (en mi caso):

    import UIKit fileprivate var ActivityIndicatorViewAssociativeKey = "ActivityIndicatorViewAssociativeKey" extension UIView { var activityIndicatorView: UIActivityIndicatorView { get { if let activityIndicatorView = objc_getAssociatedObject(self, &ActivityIndicatorViewAssociativeKey) as? UIActivityIndicatorView { return activityIndicatorView } else { let activityIndicatorView = UIActivityIndicatorView(frame: CGRect(x: 0, y: 0, width: 40, height: 40)) activityIndicatorView.activityIndicatorViewStyle = .gray activityIndicatorView.color = .gray activityIndicatorView.center = center activityIndicatorView.hidesWhenStopped = true addSubview(activityIndicatorView) objc_setAssociatedObject(self, &ActivityIndicatorViewAssociativeKey, activityIndicatorView, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) return activityIndicatorView } } set { addSubview(newValue) objc_setAssociatedObject(self, &ActivityIndicatorViewAssociativeKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) } } }

PD. Mi entorno es Xcode 10.0, iOS 12.0


Solo prueba esto:

var indicator = UIActivityIndicatorView() func activityIndicator() { indicator = UIActivityIndicatorView(frame: CGRectMake(0, 0, 40, 40)) indicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.Gray indicator.center = self.view.center self.view.addSubview(indicator) }

Y donde quieres empezar a animar.

indicator.startAnimating() indicator.backgroundColor = UIColor.whiteColor()

Para la parada:

indicator.stopAnimating() indicator.hidesWhenStopped = true

Nota: Evite las llamadas de inicio y parada en el mismo tiempo. Solo dale algunas condiciones.


Swift 2+

class ViewController: UITableViewController { weak var activityIndicatorView: UIActivityIndicatorView! override func viewDidLoad() { super.viewDidLoad() let activityIndicatorView = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.Gray) tableView.backgroundView = activityIndicatorView self.activityIndicatorView = activityIndicatorView activityIndicatorView.startAnimating() } ... }


Utilizando "lazy var". Es mejor que funcion

fileprivate lazy var activityIndicatorView: UIActivityIndicatorView = { let activityIndicatorView = UIActivityIndicatorView(activityIndicatorStyle: .gray) activityIndicatorView.hidesWhenStopped = true // Set Center var center = self.view.center if let navigationBarFrame = self.navigationController?.navigationBar.frame { center.y -= (navigationBarFrame.origin.y + navigationBarFrame.size.height) } activityIndicatorView.center = center self.view.addSubview(activityIndicatorView) return activityIndicatorView }()

Simplemente comienza el spinner en cualquier lugar

Me gusta esto

func requestData() { // Request something activityIndicatorView.startAnimating() }


RÁPIDO

Coloca esto debajo de tu clase:

let indicator:UIActivityIndicatorView = UIActivityIndicatorView (activityIndicatorStyle: UIActivityIndicatorViewStyle.Gray)

Coloca esto en tu loadView ():

indicator.color = UIColor .magentaColor() indicator.frame = CGRectMake(0.0, 0.0, 10.0, 10.0) indicator.center = self.view.center self.view.addSubview(indicator) indicator.bringSubviewToFront(self.view) indicator.startAnimating()

En mi caso, estoy solicitando objetos json a través de una solicitud de función, por lo que coloqué esto al final de esa función para eliminar el indicador de actividad una vez que se cargan los datos:

self.indicator.stopAnimating() self.indicator.hidesWhenStopped = true


Swift 3.0

// Extensión UIView

fileprivate var ActivityIndicatorViewAssociativeKey = "ActivityIndicatorViewAssociativeKey" public extension UIView { var activityIndicatorView: UIActivityIndicatorView { get { if let activityIndicatorView = getAssociatedObject(&ActivityIndicatorViewAssociativeKey) as? UIActivityIndicatorView { return activityIndicatorView } else { let activityIndicatorView = UIActivityIndicatorView(frame: CGRect(x: 0, y: 0, width: 40, height: 40)) activityIndicatorView.activityIndicatorViewStyle = .gray activityIndicatorView.color = .gray activityIndicatorView.center = center activityIndicatorView.hidesWhenStopped = true addSubview(activityIndicatorView) setAssociatedObject(activityIndicatorView, associativeKey: &ActivityIndicatorViewAssociativeKey, policy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC) return activityIndicatorView } } set { addSubview(newValue) setAssociatedObject(newValue, associativeKey:&ActivityIndicatorViewAssociativeKey, policy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC) } } }

// Extensión de NSObject

public extension NSObject { func setAssociatedObject(_ value: AnyObject?, associativeKey: UnsafeRawPointer, policy: objc_AssociationPolicy) { if let valueAsAnyObject = value { objc_setAssociatedObject(self, associativeKey, valueAsAnyObject, policy) } } func getAssociatedObject(_ associativeKey: UnsafeRawPointer) -> Any? { guard let valueAsType = objc_getAssociatedObject(self, associativeKey) else { return nil } return valueAsType } }

iniciar la animación

tableView.activityIndicatorView.startAnimating()

detener la animación

tableView.activityIndicatorView.stopAnimating()

Puedes encontrar más código en Magic


func setupSpinner(){ spinner = UIActivityIndicatorView(frame: CGRect(x: 0, y: 0, width: 40, height:40)) spinner.color = UIColor(Colors.Accent) self.spinner.center = CGPoint(x:UIScreen.main.bounds.size.width / 2, y:UIScreen.main.bounds.size.height / 2) self.view.addSubview(spinner) spinner.hidesWhenStopped = true }