0

我被困在如何从完成块内部显示视图。如果我在完成块之外使用相同的代码,则会显示视图。我确定该块正在执行,并且我还有setNeedsDisplay一个didSet用于块内的数组。那么我错过了什么?

private var storeViews = [UIView](){ didSet{self.view.setNeedsDisplay()}}

hrd.requestData(from: "somepage.php"){[weak self] (status:Bool,items:[[String:String]]?) in
    if status
    {
        for var i in (0..<items!.count)
        {
            if let item = items?[i]
            {
                var shape = CGRect()
                shape.size = CGSize(width: 50,height: 30)

                let xPosStr = item["xPosition"]
                let yPosStr = item["yPosition"]

                let position = CGPoint(x: (self?.stringToFloat(xPosStr!))!,y: (self?.stringToFloat(yPosStr!))!)

                shape.origin = position
                let someView = UIView()
                someView.frame = shape
                someView.backgroundColor = UIColor.red

                self?.view.addSubview(someView)
                self?.someViews.append(someView)
            }
        }
    }
}
4

1 回答 1

0

首先,setNeedsDisplay标记需要重绘视图的视图。这在内部调用drawRect. drawRect只有在UIView使用自己的自定义实现覆盖子类时才应该调用它。我相信您正在发出异步 API 请求,并且您正在完成块内添加视图。UI 更新应该只在主线程上完成。您需要在主线程中添加子视图

DispatchQueue.main.async {
    self?.view.addSubview(someView)
}

此外,由于您在循环中添加视图,因此您可能会查看此答案。它对 UI 更新遇到瓶颈有很好的解释。

我注意到的另一件事是,

for var i in (0..<items!.count)

如果items为 nil,您的代码将崩溃。您可以使用条件绑定来确保它不会崩溃。

if let items = items{
    for item in items{
        //Do your stuff
    }
}
于 2017-05-10T05:48:40.467 回答