如何在按下按钮时立即启动活动指示器?

问题描述:

我在应用程序中创建一个活动的指标:如何在按下按钮时立即启动活动指示器?

@IBAction func LocateMe(sender: AnyObject) { 
    Loading.hidden = false 
    Loading.startAnimating() 

} 

在viewDidLoad中是隐藏的,当我点击按钮LocateMe我要开始看到它装载在屏幕上。 问题是,它开始加载,但很晚,它开始时,应用程序打开下一个视图控制器。 你有什么想法,只要用户点击按钮,我怎么才能开始在屏幕上显示它。如果用户等待并且没有指示他已完成操作的指示符,则这是毫无用处的。我也是开放的例子。

import UIKit 
import MapKit 
import CoreLocation 
import SwiftyJSON 
import SVProgressHUD 

struct City { 

let name : String 
let location : CLLocation 
let description :String 
let imageName : NSURL 
let fileLink : NSURL 

func distanceTo(location:CLLocation) -> Int 
{ 
    let distanceMeters = location.distanceFromLocation(self.location) 
    let distanceKilometers = distanceMeters/1000.00 
    return Int(round(100 * distanceKilometers)/100) 
} 
} 

class FirstViewController: UIViewController, CLLocationManagerDelegate { 

@IBOutlet weak var Loading: UIActivityIndicatorView! 
@IBOutlet weak var LocateMeButton: UIButton! 
@IBOutlet weak var LabelTest: UILabel! 
@IBOutlet weak var Slider: UISlider! 
@IBOutlet weak var LabelValueSlider: UILabel! 
var MySliderCurrentValue = Double() 

var locationManager = CLLocationManager() 

var userLoc : CLLocation! 
var cities = [City]() 
var nearbyCities = [City]() 

override func viewDidLoad() { 
    super.viewDidLoad() 

    Loading.hidden = true 
    LocateMeButton.layer.cornerRadius = 5 

    // Do any additional setup after loading the view, typically from a nib. 

    // let path: String = NSBundle.mainBundle().pathForResource("cities", ofType: "json") as String! 
    let path = NSData(contentsOfURL: NSURL(string: "http://www.99website.eu/citiescopy.json")!) as NSData! 
    // let jsonData = NSData(contentsOfFile: path) as NSData! 
    var error : NSError? 
    let ReadableJSON2 = JSON (data:path, options: NSJSONReadingOptions.MutableContainers, error: &error) 
    print(error) 

    do { 
     let jsonObject = try NSJSONSerialization.JSONObjectWithData(path!, options: NSJSONReadingOptions.MutableContainers) as! [String:AnyObject] 
     for city in jsonObject["cities"] as! [[String:AnyObject]] { 
      //let coordinates = position["Position"] as! [String:CLLocationDegrees] 
      let cityName = city["Name"] as! String 
      let latitude = city["Latitude"] as! Double 
      let longitude = city["Longitude"] as! Double 
      let description = city["Description"] as! String 
      let image = city["Image"] as! String 
      let lin = city["Link"] as! String 
      let location = CLLocation(latitude: latitude, longitude: longitude) 
      let city = City(name: cityName, location: location,description: description, imageName: NSURL(string: image)!, fileLink: NSURL(string: lin)!) 

      cities.append(city) 

     } 

    } catch let error as NSError { 
     print(error) 
    } 


    locationManager.delegate = self 
    locationManager.desiredAccuracy = kCLLocationAccuracyBest 
    locationManager.distanceFilter = kCLDistanceFilterNone 
    locationManager.requestWhenInUseAuthorization() 
    locationManager.startMonitoringSignificantLocationChanges() 
    locationManager.startUpdatingLocation() 

    if locationManager.respondsToSelector(#selector(locationManager.requestWhenInUseAuthorization)) { 
     locationManager.requestWhenInUseAuthorization() 
     locationManager.requestLocation() 
    } 
    else { 
     locationManager.startUpdatingLocation() 
    } 


} 
+0

当你调用'LocateMe'时,你还执行了哪些其他代码。你在盯着任何位置服务吗?你正在加载一个新的'UIViewController'吗?您可能会在阻止动画的主线程上做某些事情。 – random

+0

是的,我正在开始一个位置,等我可以上传整个代码 – Dakata

+0

尝试注释掉这行代码。它会导致主线程冻结。 'let NSData(contentsOfURL:NSURL(string:“http://www.99website.eu/citiescopy.json”)!)作为NSData!'。尝试在后台线程中运行它或使用GCD。使用这个示例代码'dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0),{ // All stuff here })' –

我相信你的问题是@AsadAli所说的。您的主线程上的加载数据是同步的。你应该尝试做的是将其移动到后台线程(异步),以便你的用户界面不会被阻止。

你可以做这样的事情:

/** 
Loads the JSON data asyncrounously 

- parameter urlString: the URL 
- parameter completion: call on the main thread when the transaction is complete. Returning the data if it's there and an error if one exist. 
*/ 
func loadJSONAsync(urlString: String, completion:(data: NSData?, error: NSError?) ->()) { 

    NSURLSession.sharedSession().dataTaskWithURL(NSURL(string: urlString)!, completionHandler: { (data, response, error) -> Void in 

     dispatch_async(dispatch_get_main_queue(), {() -> Void in 
      if error != nil { 
       completion(data: nil, error: error) 
      } 
      else { 
       completion(data: data, error: nil) 
      } 
     }) 
    }).resume() 
} 

然后调用它像这样在你的viewDidLoad

loadJSONAsync("") { (data, error) in 

     if let err = error { 
      print(err) 
     } 
     else { 
      //process JSON data 
     } 

    } 

刚刚就能很快地清理你的viewDidLoad我想构建这样的:

override func viewDidLoad() { 
    super.viewDidLoad() 

    Loading.hidden = true 
    LocateMeButton.layer.cornerRadius = 5 


    // 
    // You should start showing a loading wheel heree 
    // 

    //Load the JSON 
    loadJSONAsync("http://www.99website.eu/citiescopy.json") { (data, error) in 

     if let err = error { 
      print(err) 
     } 
     else { 
      processJSON(data) 
     } 
    } 

    // Start your location manager 
    startLocationManager() 

} 

func processJSON(data: NSData) { 
    var error : NSError? 
    let ReadableJSON2 = JSON (data:path, options: NSJSONReadingOptions.MutableContainers, error: &error) 
    print(error) 

    do { 
     let jsonObject = try NSJSONSerialization.JSONObjectWithData(path!, options: NSJSONReadingOptions.MutableContainers) as! [String:AnyObject] 
     for city in jsonObject["cities"] as! [[String:AnyObject]] { 
      //let coordinates = position["Position"] as! [String:CLLocationDegrees] 
      let cityName = city["Name"] as! String 
      let latitude = city["Latitude"] as! Double 
      let longitude = city["Longitude"] as! Double 
      let description = city["Description"] as! String 
      let image = city["Image"] as! String 
      let lin = city["Link"] as! String 
      let location = CLLocation(latitude: latitude, longitude: longitude) 
      let city = City(name: cityName, location: location,description: description, imageName: NSURL(string: image)!, fileLink: NSURL(string: lin)!) 

      cities.append(city) 

      // 
      // You should stop showing a loading wheel heree 
      // 

     } 

    } catch let error as NSError { 
     print(error) 
    } 
} 

func startLocationManager() { 
    locationManager.delegate = self 
    locationManager.desiredAccuracy = kCLLocationAccuracyBest 
    locationManager.distanceFilter = kCLDistanceFilterNone 
    locationManager.requestWhenInUseAuthorization() 
    locationManager.startMonitoringSignificantLocationChanges() 
    locationManager.startUpdatingLocation() 

    if locationManager.respondsToSelector(#selector(locationManager.requestWhenInUseAuthorization)) { 
     locationManager.requestWhenInUseAuthorization() 
     locationManager.requestLocation() 
    } 
    else { 
     locationManager.startUpdatingLocation() 
    } 
} 

/** 
Loads the JSON data asyncrounously 

- parameter urlString: the URL 
- parameter completion: call on the main thread when the transaction is complete. Returning the data if it's there and an error if one exist. 
*/ 
func loadJSONAsync(urlString: String, completion:(data: NSData?, error: NSError?) ->()) { 

    NSURLSession.sharedSession().dataTaskWithURL(NSURL(string: urlString)!, completionHandler: { (data, response, error) -> Void in 

     dispatch_async(dispatch_get_main_queue(), {() -> Void in 
      if error != nil { 
       completion(data: nil, error: error) 
      } 
      else { 
       completion(data: data, error: nil) 
      } 
     }) 
    }).resume() 
} 

...你的变量名也应该是用小写声明:)