2017-04-13 1 views
0

Webインジケータが作成されるたびにアクティビティインジケータが開始され、完了したら停止する必要があります。今すぐインジケータが表示されますが、.stopAnimationはすぐに実行されており、Webリクエストが完了するのを待っていません。は、非同期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 
} 
+1

たぶん、あなたのWeb要求が;-)速いということです。 Btw:インジケータがエラーの場合に停止しないと考えてください。これは 'defer'ステートメントの良い例です。 – vadian

+0

PS:...そして通常のアドバイス:ネイティブのSwiftの対応があり、SwiftのNSArray、NSDictionaryのいずれでもない場合は、NSMutable ...を使用しないでください。 – vadian

+0

NSDictionaryの代替手段はありますか? – t2nator

答えて

0

DispatchQueueの後にself.theProgressOutlet.stopAnimating()というコードを追加します。試してみてください

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

これを試して、それが動作するかどうかを確認してください。

+0

あなたはたぶん内部を言い、後ではないと言った... –

+0

try after。それは私のために働いた –

+0

これも私のために働いた!ありがとう – t2nator

0

あなたのUIActivityIndi​​catiorを開始するコードはありません。あなたのviewDidLoadでUIActivityIndi​​catorをインスタンス化し、task.resume()の前にtheProgressOutlet.startAnimating()を呼び出すだけです。

これは、現在のコードの問題を解決することを覚えておいてください。 1つのシーンに複数の非同期要求があり、すべての呼び出しが正常に終了した後で、activityIndi​​catorをプロセスの開始時に開始して終了する必要がある場合があります。あなたの現在の状況と私が言及したものを処理するために、内部Queueが実装されたラッパークラスを作成することをお勧めします。 httpハンドラクラスを作成してリクエストをすべて行うことができますので、このプロセスを1か所で処理し、後で変更やデバッグを簡単に行うことができます。

0

dataTaskを再開する前にhidesWhenStoppedプロパティをtrueに設定し、theProgressOutletのアニメーションを開始する必要があります。働いていた上記の中でそれを入れ子

theProgressOutlet.hidesWhenStopped = true 
theProgressOutlet.startAnimating() 

let task = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) in 
    // YOUR CODE HERE 
} 
0
DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) { 
//Your code  
     } 
self.theProgressOutlet.stopAnimating() 

:)

関連する問題