Search code examples
swiftsliderconstraintsvarnslayoutconstraint

use slider to change nslayout constraint size


I want to use the slider slizer to change the size of the uiview pic. With Nslayout constraints it creates a fixed object so I added to constraints as vars. So I assume in the increase func the startCon will become deactivated and the changeCon will become activated. I have not used constraints as var in a while and dont know what to do. But I want to position pic using nslayout constraints and then change the width and height together using the slider.

    import UIKit
class ViewController: UIViewController{
    
    var pic = UIView();var slizer = UISlider()

    
    var startCon: NSLayoutConstraint!
    var changeCon: NSLayoutConstraint!


    override func viewDidLoad() {
        [pic,slizer].forEach{
            $0.translatesAutoresizingMaskIntoConstraints = false
            view.addSubview($0)
        }

        NSLayoutConstraint.activate([
            pic.centerYAnchor.constraint(equalTo: view.centerYAnchor),
            pic.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            pic.heightAnchor.constraint(equalTo: view.heightAnchor,multiplier: 0.3),
            pic.widthAnchor.constraint(equalTo: view.widthAnchor,multiplier: 0.3),
            
            slizer.bottomAnchor.constraint(equalTo: view.bottomAnchor),
            slizer.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            slizer.heightAnchor.constraint(equalTo: view.heightAnchor,multiplier: 0.2),
            slizer.widthAnchor.constraint(equalTo: view.widthAnchor,multiplier: 1),
            
            
        ])
        

        
        pic.backgroundColor = .orange
        slizer.addTarget(self, action: #selector(increase), for: .touchDown)
    }
    
    @objc func increase(){
            //increase decrease size of pic
        
    }
}

Solution

  • It's impossible to modify an activated constraints. You have to disable your contraints and set a new one.

    var pic = UIView()
    var slizer = UISlider()
    var slidermultiplier: CGFloat = 0.3
    var widthConstraints: NSLayoutConstraint?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        widthConstraints = pic.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: slidermultiplier)
        
        [pic,slizer].forEach{
            $0.translatesAutoresizingMaskIntoConstraints = false
            view.addSubview($0)
        }
        NSLayoutConstraint.activate([
            pic.centerYAnchor.constraint(equalTo: view.centerYAnchor),
            pic.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            pic.heightAnchor.constraint(equalTo: view.heightAnchor,multiplier: 0.3),
            widthConstraints!,
            
            slizer.bottomAnchor.constraint(equalTo: view.bottomAnchor),
            slizer.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            slizer.heightAnchor.constraint(equalTo: view.heightAnchor,multiplier: 0.2),
            slizer.widthAnchor.constraint(equalTo: view.widthAnchor,multiplier: 1),
        ])
        
        pic.backgroundColor = .orange
        // changed to .valueChanged
        slizer.addTarget(self, action: #selector(increase), for: .valueChanged)
    }
    
    @objc func increase() {
        slidermultiplier = CGFloat(slizer.value)
        widthConstraints?.isActive = false
        widthConstraints = pic.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: slidermultiplier)
        widthConstraints?.isActive = true
    }
    

    and you can do the same with the height. You can also set min and max value to your UISlider to have a Range of multiplier.