Search code examples
iosswift2arc4randomcgfloat

How to get a random CGFloat for a constraint?


I'm trying to randomize a leading constraint for a button in swift. To activate this I am selecting a button. When I select the button for the first time, it works well, but all the times after this, it shows a lot of errors in the NSLog. Here's the code:

let button = UIButton()
@IBAction func start(sender: UIButton) {
     let randomNumber = Int(arc4random_uniform(180) + 30)
     let cgfloatrandom = CGFloat(randomNumber)
     button.hidden = false
     button.translatesAutoresizingMaskIntoConstraints = false
     NSLayoutConstraint.activateConstraints([
        button.leadingAnchor.constraintEqualToAnchor(view.leadingAnchor, constant: cgfloatrandom),
        button.topAnchor.constraintEqualToAnchor(view.topAnchor, constant: 390),
        button.widthAnchor.constraintEqualToConstant(75),
        button.heightAnchor.constraintEqualToConstant(75)
        ])
}

Please help. Thank you. Anton


Solution

  • The problem is you're adding constraints to a button that already has been properly constrained. While you could remove all the constraints and recreate them, that is really inefficient and would not be recommended.

    I would recommend simply keeping a reference to the leading constraint, which will allow you to access it every time the button is tapped to modify the constant.

    To do this, implement a property for your leading constraint, like so:

    var leadingConstraint: NSLayoutConstraint!
    

    When you create this button, you'll want to properly constrain it as well. Here is where you'll be creating that special leading constraint. This is done outside of the button action function, perhaps in viewDidLoad:

    button = UIButton() 
    button.translatesAutoresizingMaskIntoConstraints = false
    //...
    
    leadingConstraint = button.leadingAnchor.constraintEqualToAnchor(view.leadingAnchor, constant: 0)
    
    NSLayoutConstraint.activateConstraints([
        leadingConstraint,
        button.topAnchor.constraintEqualToAnchor(view.topAnchor, constant: 390),
        button.widthAnchor.constraintEqualToConstant(75),
        button.heightAnchor.constraintEqualToConstant(75)
    ])
    

    Now when the button is tapped, you won't need to set translatesAutoresizingMaskIntoConstraints, and you can simply update the constant of the existing leading constraint.

    @IBAction func start(sender: UIButton) {
         button.hidden = false
    
         let randomNumber = Int(arc4random_uniform(180) + 30)
         leadingConstraint.constant = CGFloat(randomNumber)
    }