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

霸气de小男生 提交于 2019-12-22 10:12:20

问题


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?


回答1:


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
        }
    }

}


来源:https://stackoverflow.com/questions/31968547/nslayoutconstraint-that-would-pin-a-view-to-the-bottom-edge-of-a-superview

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!