异步Web请求后无法停止活动指示器

时间:2017-04-13 18:20:09

标签: ios swift uiactivityindicatorview

我需要活动指示器在Web请求发出时启动,并在完成后停止。现在,指示器将显示,但.stopAnimation正在执行,甚至没有等待Web请求完成。

import UIKit


class ViewController: 
UIViewController,UIPickerViewDelegate,UIPickerViewDataSource {

@IBOutlet weak var locationPickerOutlet: UIPickerView!
@IBOutlet weak var theProgressOutlet: UIActivityIndicatorView!

var locationspickerData: [String] = [String]()

override func viewDidLoad() {
    super.viewDidLoad()

    populateLocations()

}


func populateLocations() {

    self.locationspickerData = ["All Locations"]
    let url:URL = URL(string: "http://<web address>")!
    let session = URLSession.shared
    let request = NSMutableURLRequest(url: url)
    request.httpMethod = "GET"
    //request.cachePolicy = NSURLRequest.CachePolicy.reloadIgnoringCacheData
    let task = session.dataTask(with: request as URLRequest, completionHandler: {
        (data, response, error) in
        guard let _:Data = data, let _:URLResponse = response  , error == nil else {
            return
        }

        let json: Any?
        do
        {
            json = try JSONSerialization.jsonObject(with: data!, options: [])
        }
        catch
        {
            return
        }
        guard let data_list = json as? NSArray else
        {
            return
        }
        if let locations_list = json as? NSArray
        {

            for i in 0 ..< data_list.count
            {
                if let locations_obj = locations_list[i] as? NSDictionary
                {
                    if let location_name = locations_obj["name"] as? String
                    {
                        self.locationspickerData.append(location_name)
                    }
                }
            }


            self.locationPickerOutlet.delegate = self
            self.locationPickerOutlet.dataSource = self
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
                self.theProgressOutlet.stopAnimating()
            }

        }

    })

    task.resume()

}



override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}


func numberOfComponents(in pickerView: UIPickerView) -> Int {
    return 1
}

func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
    return locationspickerData.count
}


func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
    return locationspickerData[row]
}

func pickerView(_ pickerView: UIPickerView, attributedTitleForRow row: Int, forComponent component: Int) -> NSAttributedString? {
    let titleData = locationspickerData[row]
    let myTitle = NSAttributedString(string: titleData, attributes: [NSFontAttributeName:UIFont(name: "Georgia", size: 15.0)!,NSForegroundColorAttributeName:UIColor.blue])
    return myTitle
}

4 个答案:

答案 0 :(得分:0)

我没有看到启动UIActivityIndi​​catior的代码。只需在viewDidLoad中实例化UIActivityIndi​​cator,然后在task.resume()之前调用theProgressOutlet.startAnimating()。

请记住,这解决了当前代码的问题。情况发生在一个场景中有多个异步请求,activityIndi​​cator需要在进程开始时启动,并在所有调用成功完成后结束。为了处理您当前的情况和我提到的情况,我建议您创建一个包含内部队列的包装器类。您还可以创建一个http处理程序类来发出所有请求,这样您就可以在一个地方处理此过程,并使以后的更改和调试更容易。

答案 1 :(得分:0)

在DispatchQueue之后添加代码self.theProgressOutlet.stopAnimating()。试试这个

DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
//Your code    
            }
self.theProgressOutlet.stopAnimating()

试一下,看看它是否有效。

答案 2 :(得分:0)

您应该将hidesWhenStopped属性设置为true,并在恢复theProgressOutlet之前开始为dataTask设置动画。

theProgressOutlet.hidesWhenStopped = true
theProgressOutlet.startAnimating()

let task = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) in
    // YOUR CODE HERE
}

答案 3 :(得分:0)

function add_to_table_1() {
    $('#1')
        .append('<tr><td>' + sel.html() + '</td><td><input type="text" id="e"></input></td><td><input type="text" id="S"></input></td><td><input type="itext" id="r"></input></td><td><button onclick="delete_row(this)">Borrar</button></td></tr>');
}

将它嵌套在上面的工作中:)