Как отобразить программный вид в обработчике завершения?

Я застрял на том, как отобразить вид из блока завершения. Если я использую тот же код за пределами блока завершения, отображается вид. Я уверен, что блок выполняется, и у меня также есть 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)
            }
        }
    }
}

1 ответ

Во-первых, setNeedsDisplay отмечает представление о том, что оно должно быть перерисовано. Это внутренне называет drawRect, Вы должны называть это, только если вы переопределите drawRect в UIView подкласс с вашей собственной пользовательской реализацией. Я полагаю, что вы делаете асинхронный запрос API и добавляете представления внутри блока завершения. Обновления пользовательского интерфейса должны выполняться только в основном потоке. Вам нужно добавить подпредставление в основной теме

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

Кроме того, поскольку вы добавляете представления в цикл, вы можете посмотреть на этот ответ. У этого есть действительно хорошее объяснение об узких местах обновлений пользовательского интерфейса.

Еще одна вещь, которую я заметил, это

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

Если items ноль, ваш код не работает. Вы можете сделать это с условной привязкой, чтобы убедиться, что она не падает.

if let items = items{
    for item in items{
        //Do your stuff
    }
}
Другие вопросы по тегам