#ios #swift
#iOS #swift
Вопрос:
class ViewController: UIViewController {
let manImage = UIImage(named: "man.png")
let buttons = (0..<5).map({_ in UIButton()})
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
createButtons()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func createButtons() {
var pos = 25
for index in 0...4 {
delay(Double(arc4random_uniform(5)) 5) {
self.buttons[index].setBackgroundImage(self.manImage, forState: .Normal)
self.buttons[index].translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(self.buttons[index])
self.view.addConstraint(NSLayoutConstraint(
item: self.buttons[index],
attribute: .Leading,
relatedBy: .Equal,
toItem: self.view,
attribute: .Leading,
multiplier: 1,
constant: CGFloat(pos)))
pos = 10
}
}
}
func delay(delay:Double, closure:()->()) {
dispatch_after(
dispatch_time(
DISPATCH_TIME_NOW,
Int64(delay * Double(NSEC_PER_SEC))
),
dispatch_get_main_queue(), closure)
}
}
Я использовал кучу примеров кода с разной задержкой по времени из поиска, но весь код приводит к тому, что некоторые кнопки отображаются одновременно. Из строки кода
delay(Double(arc4random_uniform(5)) 5)
разве это не означает задержку не менее 5 секунд между каждой итерацией цикла for? Почему он это делает?
Спасибо.
Ответ №1:
Решение, аналогичное вашему первоначальному подходу, может заключаться в том, чтобы сделать задержку для каждой последовательной кнопки относительно предыдущей.
func createButtons() {
var delayTime = 0.0
var pos = 25
for index in 0...4 {
delayTime = delayTime Double(arc4random_uniform(5)) 5
delay(delayTime) {
self.buttons[index].setBackgroundImage(self.manImage, forState: .Normal)
self.buttons[index].translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(self.buttons[index])
self.view.addConstraint(NSLayoutConstraint(
item: self.buttons[index],
attribute: .Leading,
relatedBy: .Equal,
toItem: self.view,
attribute: .Leading,
multiplier: 1,
constant: CGFloat(pos)))
pos = 10
}
}
}
Комментарии:
1. Что ж, это, безусловно, работает. Спасибо. Но есть ли причина, по которой мой исходный код иногда сбивался, а иногда нет?
2. Да, конечно! Ваш исходный код запускал все таймеры одновременно, каждый со случайной задержкой от 5 до 10 секунд … иногда они были разнесены, а иногда нет, просто случайно.
Ответ №2:
Ваш код создает четыре задержки произвольной длины, но он создает их примерно в одно и то же время и запускает их параллельно, поэтому вполне возможно, что некоторые из случайных задержек будут примерно такой же длины, как и другие, и кнопки будут отображаться одновременно.
Возможно, вы захотите попробовать создать кнопку, затем отложить на случайное время, создать другую кнопку, затем снова отложить и т. Д. Разница в том, что вы должны создавать случайную задержку между созданием кнопок, а не создавать все четыре задержки одновременно. Для этого хорошо подойдет рекурсивная функция.
Просто будьте осторожны, чтобы не блокировать основной поток во время задержек. Приведенный выше код выглядит правильным в этом отношении, но продолжайте быть осторожными в этом вопросе.
Комментарии:
1. Извините, вы правы. Моя тема неверна. Я это исправлю.