Reputation:
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)
}
}
I've been using a bunch of different time delay sample code from searching, but all code results in some of the buttons to be displayed at the same time. From the line of code
delay(Double(arc4random_uniform(5)) + 5)
does this not mean to delay at least 5 seconds between each iteration of the for loop? Why does it do this?
Thank you.
Upvotes: 0
Views: 49
Reputation: 160
A solution similar to your original approach might be to make the delay for each consecutive button relative to the previous one.
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
}
}
}
Upvotes: 0
Reputation: 22701
Your code creates four delays of random length, but it creates them at about the same time and runs them in parallel, so it's quite possible that some of the random delays will be about the same length as others and the buttons will appear to display at the same time.
You might want to try creating a button, then delaying for a random time, the creating another button, then delaying again, etc. The difference being is that you should create a random delay between button creations, rather than creating all four delays at once. A recursive function would work well for this.
Just be careful not to block the main thread during the delays. The above code looks correct in this regard, but continue to be careful in this matter.
Upvotes: 0