简体   繁体   中英

NSLayoutConstraint that would pin a view to the bottom edge of a superview

A reproducible example

class ViewController: UIViewController {

   var created = false

   override func viewDidLayoutSubviews() {
      super.viewDidLayoutSubviews()
      if !created {

         let scrollView = UIScrollView()
         scrollView.backgroundColor = UIColor.grayColor()
         view.addSubview(scrollView)

         let kidView = UIView()
         kidView.backgroundColor = UIColor.redColor()
         kidView.translatesAutoresizingMaskIntoConstraints = false

         scrollView.addSubview(kidView)

         scrollView.translatesAutoresizingMaskIntoConstraints = false
         kidView.translatesAutoresizingMaskIntoConstraints = false

         view.addConstraints(
            NSLayoutConstraint.constraintsWithVisualFormat("H:|[scrollView]|", options: .AlignAllLeft, metrics: nil, views: ["scrollView": scrollView])
         )
         view.addConstraints(
            NSLayoutConstraint.constraintsWithVisualFormat("V:|[scrollView]|", options: .AlignAllLeft, metrics: nil, views: ["scrollView": scrollView])
         )

         kidView.addConstraints([
            NSLayoutConstraint(item: kidView, attribute: .Width, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: 100),
            NSLayoutConstraint(item: kidView, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: 100),
         ])

         scrollView.addConstraints([
            NSLayoutConstraint(item: kidView, attribute: .CenterX, relatedBy: .Equal, toItem: scrollView, attribute: .CenterX, multiplier: 1, constant: 0),
            NSLayoutConstraint(item: kidView, attribute: .Bottom, relatedBy: .Equal, toItem: scrollView, attribute: .Bottom, multiplier: 1, constant: 0),
//            NSLayoutConstraint(item: kidView, attribute: .CenterY, relatedBy: .Equal, toItem: scrollView, attribute: .CenterY, multiplier: 1, constant: 0),
         ])

         created = true
      }
   }

}

Problem

I want to align my custom view to the bottom edge of my UIScrollView , but I can only seem to align it to the top, or vertical center.

scrollView.addConstraints([
    NSLayoutConstraint(
        item: circleContainerView, 
        attribute: .Top, 
        relatedBy: .Equal, 
        toItem: scrollView, 
        attribute: .Top, 
        multiplier: 1, 
        constant: 0),
])

在此输入图像描述

scrollView.addConstraints([
    NSLayoutConstraint(
        item: circleContainerView, 
        attribute: .CenterY, 
        relatedBy: .Equal, 
        toItem: scrollView, 
        attribute: .CenterY, 
        multiplier: 1, 
        constant: 0),
])

在此输入图像描述

But what I want is to have a picture like this. How do I get there?

在此输入图像描述

ScrollView with auto layout works differently either you can use only one subview by setting translatesAutoresizingMaskIntoConstraints = true and setting contentSize explicitly. Or you set translatesAutoresizingMaskIntoConstraints = false and let it find out constraint it self.

In your case you can add an invisible view inside scroll and pin it to top and set its height to scrollView.bounds.size.height and then set create constraint with that invisible view

Change your constraint like this

scrollView.addConstraints([
    NSLayoutConstraint(
        item: circleContainerView, 
        attribute: .Bottom, 
        relatedBy: .Equal, 
        toItem: invisibleView, 
        attribute: .Bottom, 
        multiplier: 1, 
        constant: 0),
])

Visit this link for more details, read pure auto layout approach

Update: your modified code

class ViewController: UIViewController {

    var created = false

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        if !created {

            let scrollView = UIScrollView()
            scrollView.backgroundColor = UIColor.grayColor()
            view.addSubview(scrollView)

            let kidView = UIView()
            kidView.backgroundColor = UIColor.redColor()

            scrollView.addSubview(kidView)

            scrollView.translatesAutoresizingMaskIntoConstraints = false
            kidView.translatesAutoresizingMaskIntoConstraints = false

            scrollView.frame = view.bounds;
            scrollView.contentSize = view.bounds.size

            // Add an invisible view

            let inV = UIView()
            inV.backgroundColor = UIColor.clearColor()
            inV.translatesAutoresizingMaskIntoConstraints = false
            scrollView.addSubview(inV)


            view.addConstraints(
                NSLayoutConstraint.constraintsWithVisualFormat("H:|[scrollView]|", options: .AlignAllLeft, metrics: nil, views: ["scrollView": scrollView])
            )
            view.addConstraints(
                NSLayoutConstraint.constraintsWithVisualFormat("V:|[scrollView]|", options: .AlignAllLeft, metrics: nil, views: ["scrollView": scrollView])
            )

            var constraint = NSLayoutConstraint(item: inV, attribute: .Top, relatedBy: .Equal, toItem: scrollView, attribute: .Top, multiplier: 1, constant: 0)

            view.addConstraint(constraint)

            constraint = NSLayoutConstraint(item: inV, attribute: .Left, relatedBy: .Equal, toItem: scrollView, attribute: .Left, multiplier: 1, constant: 0)
            view.addConstraint(constraint)

            inV.addConstraints([
                NSLayoutConstraint(item: inV, attribute: .Width, relatedBy: .Equal, toItem: nil, attribute: .Width, multiplier: 1, constant: 10),
                NSLayoutConstraint(item: inV, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .Height, multiplier: 1, constant: self.view.bounds.size.height),
                ])

            //

            kidView.addConstraints([
                NSLayoutConstraint(item: kidView, attribute: .Width, relatedBy: .Equal, toItem: nil, attribute: .Width, multiplier: 1, constant: 100),
                NSLayoutConstraint(item: kidView, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .Height, multiplier: 1, constant: 100),
                ])

            view.addConstraints([
                NSLayoutConstraint(item: kidView, attribute: .CenterX, relatedBy: .Equal, toItem: scrollView, attribute: .CenterX, multiplier: 1, constant: 0),
                NSLayoutConstraint(item: kidView, attribute: .Bottom, relatedBy: .Equal, toItem: inV, attribute: .Bottom, multiplier: 1, constant: 0),
                ])

            created = true
        }
    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM