Search code examples
iosswiftuiactivityindicatorviewuiactivity

UIActivity indicator or spinner in this case indicator is not showing up


So, I have written a program that is a map app which allows user to see there location when they open the app and when they double tap it allows them to drop a pin the bottom view which is hidden shows up and i want to show images in that view since i made the hight of the view really small i cant use storyboard to add components in it and i added a activity indicator
with code but for some reason the activity indicator is not showing up on the screen even when the hight of the hidden view changes and it comes up. this is the code

import UIKit
import MapKit
import CoreLocation
class MapVC: UIViewController, UIGestureRecognizerDelegate {


@IBOutlet weak var pullUpViewHighConstraint: NSLayoutConstraint!
@IBOutlet weak var pullUpView: UIView!
@IBOutlet weak var mapView: MKMapView!


var locationManager = CLLocationManager()
var authStatus = CLLocationManager.authorizationStatus()
let regiounRadius: Double = 1000
var spinner: UIActivityIndicatorView?
var progrssLabel: UILabel?
var screen = UIScreen.main.bounds



override func viewDidLoad() {
    super.viewDidLoad()
    mapView.delegate = self
    locationManager.delegate = self
    locationManager.desiredAccuracy = kCLLocationAccuracyBest
    self.mapView.showsUserLocation = true
    configureLocationServices()
    addDoubleTap()
}


func addDoubleTap() {
    let doubleTap = UITapGestureRecognizer(target: self, action:  #selector(droupPin(sender:)))
    doubleTap.numberOfTapsRequired = 2
    doubleTap.delegate = self

    mapView.addGestureRecognizer(doubleTap)
}

func addSwipe() {
    let swipe = UISwipeGestureRecognizer(target: self, action:  #selector(animateViewDown))
    swipe.direction = .down
    pullUpView.addGestureRecognizer(swipe)
}

func animateViewUp() {
    pullUpViewHighConstraint.constant = 300
    UIView.animate(withDuration: 0.4) {
        self.view.layoutIfNeeded()
    }

}

@objc func animateViewDown() {
    pullUpViewHighConstraint.constant = 0
    UIView.animate(withDuration: 0.4) {
        self.view.layoutIfNeeded()
    }
}

func addSpinner() {
    spinner = UIActivityIndicatorView()
    spinner?.center = CGPoint(x: screen.width / 2 -  (spinner?.frame.width)! / 2, y: 150)
    spinner?.activityIndicatorViewStyle = .whiteLarge
    spinner?.color = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1)
    spinner?.stopAnimating()
    pullUpView.addSubview(spinner!)
}


@IBAction func centerMapBtnPressed(_ sender: Any) {
    if authStatus == .authorizedAlways || authStatus ==  .authorizedWhenInUse{
        centerMapOnUserLocation()
        // removePin()

    }else {return}
}

}

 extension MapVC: MKMapViewDelegate {

func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
    if annotation is MKUserLocation {
        return nil
    }
    let pinAnnotation = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "droppablePin")
    pinAnnotation.pinTintColor = #colorLiteral(red: 0.9771530032, green: 0.7062081099, blue: 0.1748393774, alpha: 1)
    pinAnnotation.animatesDrop = true
    return pinAnnotation
}

func centerMapOnUserLocation() {
    guard let coordinets = locationManager.location?.coordinate else    { return }
    let coordinateRegion =    MKCoordinateRegionMakeWithDistance(coordinets, regiounRadius*2.0,  regiounRadius*2.0)
    mapView.setRegion(coordinateRegion, animated: true)
}

@objc func droupPin(sender: UITapGestureRecognizer) {
    removePin()
    animateViewUp()
    addSwipe()
    addSpinner()
    let touchPoint = sender.location(in: mapView)
    let touchCoordinate = mapView.convert(touchPoint, toCoordinateFrom: mapView)
    let annotation = DroppablePin(coordinatee: touchCoordinate, identifierr: "droppablePin")
    mapView.addAnnotation(annotation)

    let coordinateRegion =  MKCoordinateRegionMakeWithDistance(touchCoordinate, regiounRadius*2.0, regiounRadius*2.0)
    mapView.setRegion(coordinateRegion, animated: true)

}

func removePin() {
    for annotation in mapView.annotations {
        mapView.removeAnnotation(annotation)
    }
}

}

extension MapVC: CLLocationManagerDelegate {

func configureLocationServices() {
    if authStatus == .notDetermined {
        locationManager.requestAlwaysAuthorization()
    }
    else {
        return
    }
}

func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
    centerMapOnUserLocation()
}

}

Solution

  • First the spinner is not showing because you don't position it correctly , Second you should use startAnimating() to animate the spinner , Here you try to position the spinner in middle x,y of the pullView

        spinner = UIActivityIndicatorView() 
        spinner.translatesAutoresizingMaskIntoConstraints = false     
        spinner?.activityIndicatorViewStyle = .whiteLarge
        spinner?.color =  colorLiteral(red: 0, green: 0, blue: 0, alpha: 1)
        pullUpView.addSubview(spinner!)
       // center in container
        spinner.centerXAnchor.constraint(equalTo: pullUpView.centerXAnchor).isActive = true
        spinner.centerYAnchor.constraint(equalTo: pullUpView.centerYAnchor).isActive = true
        spinner?.startAnimating()
    

    This is the best time to use auto-layout as while you use frame-layout to show the spinner the pullUpView frame is changed which will result in an incorrect render , put with auto-layout it will render perfectly