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