View不是异步添加子视图Swift

时间:2017-02-15 08:42:30

标签: ios swift user-interface asynchronous uiview

我正在使用Swift作为iOS Developer我最近以异步方式添加子视图时遇到了一些麻烦,我正在使用 dispatch_async(dispatch_get_main_queue(),但它仍然不起作用。子视图不是一个接一个地实时添加,但是我必须等到调用完成然后更新UI。我的目标是逐个添加子视图,并且for循环仍然是实时的下面是我的代码的一部分。如果有人可以帮助我,我会非常感激。

for i in 0 ..< self.allChannels.count {
        let param = Params().getEpgParams(String(self.allChannels[i].channelNumber))    
        uNetwork().httpRequestNoLoading(self.utilityClass.currentServer , parameters: param, method: uNetwork.METHOD.POST,  parent: self) { (epgResponse, extra_information) -> () in

            if(extra_information != uNetwork.EXTRA_INFORMATION.SUCCESS){
                self.presentViewController(self.utilityClass.alert("Error", message: "An Unexpected Error Happened"), animated: true, completion: nil)
            } else if(epgResponse == nil){
                self.presentViewController(self.utilityClass.alert("Error", message: "Couldn't get any response from the server"), animated: true, completion: nil)
            } else {
                do {
                    var titleArray = [String]()
                    var start = [String]()
                    var end = [String]()
                    var progressArray = [Float]()

                    let jsonObject = try NSJSONSerialization.JSONObjectWithData(epgResponse, options: []) as! NSDictionary
                    if let response_object = jsonObject["response_object"] as? [[String: AnyObject]] {
                        for menu in response_object{
                            titleArray.append(menu["title"] as! String)
                            start.append(menu["programstart"] as! String)
                            end.append(menu["programend"] as! String)
                            progressArray.append(menu["progress"] as! Float)
                        }



                        if(titleArray.count > 0){
                            currentTitle = titleArray[0]
                            currentStart = start[0][start[0].startIndex.advancedBy(12)..<start[0].startIndex.advancedBy(12+4)]
                            currentEnd = end[0][end[0].startIndex.advancedBy(12)..<end[0].startIndex.advancedBy(12+4)]
                            progressValue = Float(progressArray[0] / 100)
                        } else {
                            currentTitle = "Programet e \(self.allChannels[i].title)"
                            currentStart = "00:00"
                            currentEnd = "00:00"
                            progressValue = 0.5
                        }

                            dispatch_async(dispatch_get_main_queue(), {
                            indiSub[i].removeFromSuperview()

                           self.contentView = UIView(frame: CGRectMake(0, ((self.scrollView.frame.height / 4) * CGFloat(i)), self.epgView.frame.width, self.scrollView.frame.height / 4))
                            self.contentView.layer.masksToBounds = true
                            self.scrollView.addSubview(self.contentView)

                            let button = UIButton(frame: CGRectMake(0, ((self.scrollView.frame.height / 4) * CGFloat(i)), self.epgView.frame.width, self.scrollView.frame.height / 4))
                            button.tag = Int(self.allChannels[i].channelNumber)
                            button.addTarget(self, action: #selector(LiveTvTest.playFromEpg(_:)), forControlEvents: .TouchUpInside)
                            self.scrollView.addSubview(button)

                            let currentTime = UILabel(frame: CGRectMake((self.scrollView.frame.height / 4) + 25, 0, 60, self.contentView.frame.height / 3))
                            if currentStart.characters.count == 4{
                                currentTime.text = currentStart + "     |"
                            } else if (currentStart.characters.count == 5){
                                currentTime.text = currentStart + "   |"
                            }
                            currentTime.font = UIFont(name: "Helvetica Neue", size: 15)
                            currentTime.adjustsFontSizeToFitWidth = true
                            currentTime.textColor = UIColor(red:0.54, green:0.13, blue:0.13, alpha:1.0)
                            self.contentView.addSubview(currentTime)

                            let nextTime = UILabel(frame: CGRectMake((self.scrollView.frame.height / 4) + 25, currentTime.frame.height, 60, self.contentView.frame.height / 3))
                            if nextStart.characters.count == 4{
                                nextTime.text = nextStart + "     |"
                            } else if (nextStart.characters.count == 5) {
                                nextTime.text = nextStart + "   |"
                            }
                            nextTime.font = UIFont(name: "Helvetica Neue", size: 15)
                            nextTime.adjustsFontSizeToFitWidth = true
                            nextTime.textColor = UIColor(red:0.53, green:0.53, blue:0.53, alpha:1.0)
                            self.contentView.addSubview(nextTime)
                           })


                    } else {
                        print("something went wrong with response object")
                    }




                } catch {
                    self.presentViewController(self.utilityClass.alert("Error", message: "Something went wrong, please try again later"), animated: true, completion: nil)
                }
            }
        }
    }

2 个答案:

答案 0 :(得分:0)

如果你可以确保你的闭包(你交给httpRequestNoLoading)在一个任意线程中运行,你可以使用dispatch_sync你的UI更新到主线程中;这将等待工作项执行。但如果关闭已经在主线程中运行,那肯定会陷入僵局。

顺便说一下。您还应该将presentViewController个调用发送到主线程中。

答案 1 :(得分:0)

我猜问题是你正在设置一组http调用。这些调用并行执行并通过回调返回。然后,您将几个视图更新非常紧密地组合在一起,因此,即使代码是串行的,更新也会快速连续发生。

那就是说,要记住的另一件事是osx / ios批量他们的ui更新。因此,你可能会立即在mainQueue上投入大量工作,并且没有机会看到工作发生。为什么不尝试使用dispatch_after添加一些随机延迟来查看是否会在不同时间弹出内容?