1

I'm setting constraints to image view programmatically like so:

        imgScrollView = UIScrollView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
        imgScrollView.showsHorizontalScrollIndicator = false
        imgScrollView.showsVerticalScrollIndicator = false
        imgScrollView.bouncesZoom = false
        imgScrollView.bounces = false

        view.addSubview(imgScrollView)

        imgScrollView.translatesAutoresizingMaskIntoConstraints = false
        imgScrollView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 0).isActive = true
        imgScrollView.bottomAnchor.constraint(equalTo: toolBar.topAnchor, constant: -100).isActive = true
        imgScrollView.leftAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leftAnchor, constant: 0).isActive = true
        imgScrollView.rightAnchor.constraint(equalTo: view.safeAreaLayoutGuide.rightAnchor, constant: 0).isActive = true



        // add image view to scrollview
        imgView = UIImageView(frame: CGRect(x: 0, y: 0,width: 100, height: 100))

        imgScrollView.addSubview(imgView)
        imgView.translatesAutoresizingMaskIntoConstraints = false

        imgView.topAnchor.constraint(equalTo: imgScrollView.contentLayoutGuide.topAnchor, constant: 0).isActive = true
        imgView.bottomAnchor.constraint(equalTo: imgScrollView.contentLayoutGuide.bottomAnchor, constant: 0).isActive = true
        imgView.leftAnchor.constraint(equalTo: imgScrollView.contentLayoutGuide.leftAnchor, constant: 0).isActive = true
        imgView.rightAnchor.constraint(equalTo: imgScrollView.contentLayoutGuide.rightAnchor, constant: 0).isActive = true


        imgView.widthAnchor.constraint(equalTo: imgScrollView.widthAnchor, multiplier: 1).isActive = true

Now later on with button tap I'm adding additional constraint

imgView.heightAnchor.constraint(equalTo: imgScrollView.heightAnchor, multiplier: 1).isActive = true

However the constraint is not being added. Why is it happening?

7
  • @mezzi Why don't you just add the height constraint in the beginning itself, and just change its constant on button tap? Commented May 1, 2020 at 21:45
  • well what you are trying to do ? giving left right constraint and also giving width with them ... they will conflict ... same is the case with bottom and top ...giving hight as well... Commented May 1, 2020 at 21:49
  • when I add all of the constraints left, right and width, height in the beginning when imgView is created there's no problem. No conflicts. Everything works as expected. It's when I try to add height constraint afterwards on button tap, the constraint is not being added Commented May 1, 2020 at 21:52
  • @badhanganesh what do you mean? Should I put nil for constant in the beginning? Commented May 1, 2020 at 21:54
  • 1
    I don't know what you do on the button tap, but instead of adding a new height constraint on button tap, you can add the height constraint in the beginning with height zero or something (or any default value), and then on button tap, you can change that height constant to whatever new value you want. You have to store the (height) constraint that you wish to change. Commented May 1, 2020 at 21:57

1 Answer 1

1

Your implementation logic working for me.

  • Left image show implementation without height constraint.
  • Right image show button pressed with height constraint.

In function viewDidLoad

override func viewDidLoad() {
  super.viewDidLoad()
  view.backgroundColor = .white
  scrollView.isScrollEnabled = true
  scrollView.bounces = false
  scrollView.alwaysBounceVertical = true
  imageView.image = UIImage(color: .lightGray)

  navigationItem.rightBarButtonItem = barButtonItem
  view.addSubview(scrollView)
  scrollView.addSubview(imageView)

  scrollView.translatesAutoresizingMaskIntoConstraints = false
  imageView.translatesAutoresizingMaskIntoConstraints = false
  NSLayoutConstraint.activate([
    scrollView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
    scrollView.leftAnchor.constraint(equalTo: view.leftAnchor),
    scrollView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
    scrollView.rightAnchor.constraint(equalTo: view.rightAnchor)
  ])
  NSLayoutConstraint.activate([
    imageView.topAnchor.constraint(equalTo: scrollView.contentLayoutGuide.topAnchor),
    imageView.leftAnchor.constraint(equalTo: scrollView.contentLayoutGuide.leftAnchor),
    imageView.bottomAnchor.constraint(equalTo: scrollView.contentLayoutGuide.bottomAnchor),
    imageView.rightAnchor.constraint(equalTo: scrollView.contentLayoutGuide.rightAnchor),
    imageView.widthAnchor.constraint(equalTo: scrollView.widthAnchor)
  ])
}

In function buttonPressed

@objc func buttonPressed() {
  navigationItem.rightBarButtonItem = nil
  UIView.animate(withDuration: 1) {
    NSLayoutConstraint.activate([
      self.imageView.heightAnchor.constraint(equalTo: self.scrollView.heightAnchor)
    ])
    self.view.setNeedsLayout()
    self.view.layoutIfNeeded()
  }
}

UIImage util Create UIImage with solid color in Swift

fileprivate extension UIImage {
  convenience init?(color: UIColor, size: CGSize = CGSize(width: 1, height: 1)) {
    let rect = CGRect(origin: .zero, size: size)
    UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0)
    color.setFill()
    UIRectFill(rect)
    let image = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    guard let cgImage = image?.cgImage else { return nil }
    self.init(cgImage: cgImage)
  }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Setting constraints with NSLayoutConstraint.activate() did the trick. Not it works as expected. Thank you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.