简体   繁体   English

如何让我的活动指标在合适的时间开始?

[英]How do I get my Activity Indicator to start at the right time?

From everything I read you can activate it with with a button so I put it right after the button action that starts the http POST and upload, but right now it starts spinning right after the function has finished, after the upload is complete, the opposite of what I would expect. 从我阅读的所有内容中,您可以使用按钮激活它,所以我在启动http POST和上传的按钮操作后立即执行,但是现在它在功能完成后立即开始旋转,上传完成后,相反我所期待的。
I'm new to Swift so please explain your answer as you would to a nubie. 我是Swift的新手所以请解释你的答案,就像你对一个nubie一样。 Many thanks. 非常感谢。

@IBAction func upload(sender: AnyObject) {

    myActivityIndicator.startAnimating()

    var imageData = UIImagePNGRepresentation(myImageView.image)

    if imageData != nil{
        var request = NSMutableURLRequest(URL: NSURL(string:"http://www.example.com/upload.php")!)

        var session = NSURLSession.sharedSession()

        request.HTTPMethod = "POST"

        var boundary = NSString(format: "---------------------------14737809831466499882746641449")
        var contentType = NSString(format: "multipart/form-data; boundary=%@",boundary)
        //  println("Content Type \(contentType)")
        request.addValue(contentType, forHTTPHeaderField: "Content-Type")

        var body = NSMutableData.alloc()

        // Title
        body.appendData(NSString(format: "\r\n--%@\r\n",boundary).dataUsingEncoding(NSUTF8StringEncoding)!)
        body.appendData(NSString(format:"Content-Disposition: form-data; name=\"title\"\r\n\r\n").dataUsingEncoding(NSUTF8StringEncoding)!)
        body.appendData("Hello World".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)!)

        // Image
        body.appendData(NSString(format: "\r\n--%@\r\n", boundary).dataUsingEncoding(NSUTF8StringEncoding)!)
        body.appendData(NSString(format:"Content-Disposition: form-data; name=\"profile_img\"; filename=\"img.jpg\"\r\n").dataUsingEncoding(NSUTF8StringEncoding)!)
        //           println("body=\(body)")
        body.appendData(NSString(format: "Content-Type: application/octet-stream\r\n\r\n").dataUsingEncoding(NSUTF8StringEncoding)!)
        body.appendData(imageData)
        body.appendData(NSString(format: "\r\n--%@\r\n", boundary).dataUsingEncoding(NSUTF8StringEncoding)!)



        request.HTTPBody = body


        var returnData = NSURLConnection.sendSynchronousRequest(request, returningResponse: nil, error: nil)

        var returnString = NSString(data: returnData!, encoding: NSUTF8StringEncoding)

        println("returnString \(returnString)")

        //self.myActivityIndicator.stopAnimating()
        //self.myImageView.image = nil

    }


}

try this 尝试这个

myActivityIndicator.startAnimating()        
          dispatch_async(dispatch_get_global_queue(Int(QOS_CLASS_USER_INITIATED.value), 0)) {
            //Do your post code here or call the post func
            dispatch_async(dispatch_get_main_queue()) {
                myActivityIndicator.stopAnimating()
            }
    }

http://ijoshsmith.com/2014/07/29/a-swift-app-that-calls-json-web-services/ http://www.raywenderlich.com/79149/grand-central-dispatch-tutorial-swift-part-1 http://ijoshsmith.com/2014/07/29/a-swift-app-that-c​​alls-json-web-services/ http://www.raywenderlich.com/79149/grand-central-dispatch-tutorial-迅速部分-1

This is occurring because this call is blocking the main thread (which is responsible for updating the UI: 发生这种情况是因为此调用阻止了主线程(负责更新UI):

var returnData = NSURLConnection.sendSynchronousRequest(request, returningResponse: nil, error: nil)

Thus, after this line of code everything you do on the UI will not show up until after this synchronous call has completed. 因此,在此行代码之后,您在UI上执行的所有操作都将在此同步调用完成之后才会显示。

The solution here is to make this call on a background thread, and then when finished update the UI on the main thread. 这里的解决方案是在后台线程上进行此调用,然后在完成时更新主线程上的UI。

One of the nicest ways to achieve this is using GCD (Grand Central Dispatch). 实现这一目标的最好方法之一是使用GCD(Grand Central Dispatch)。 GCD is a thread API which makes doing work on a background thread easy peasy. GCD是一个线程API,它使得在后台线程上工作很容易。

As already mentioned in the answer above: 正如上面的答案中已经提到的:

    dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INTERACTIVE, 0), {

        var returnData = NSURLConnection.sendSynchronousRequest(request, returningResponse: nil, error: nil)

        dispatch_async(dispatch_get_main_queue()) {
            myActivityIndicator.stopAnimating()
        }

    })

One of the key tenets in iOS development is not blocking the main thread. iOS开发中的一个关键原则是不阻塞主线程。

This leads to a bad user experience. 这会导致糟糕的用户体验。

Furthermore, it's really important to always update the UI on the main thread. 此外,始终更新主线程上的UI非常重要。

Just so you know there are other ways to handle this kind of situation without GCD (threading API), NSOperation for example. 只是你知道还有其他方法可以在没有GCD(线程API)的情况下处理这种情况,例如NSOperation

Also, you could send an asynchronous request instead. 此外,您可以发送异步请求。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM