0

I'm creating new UIViewController dynamycally using this code

@IBAction func newVCBtnPressed(_ sender: Any) {
            let controller = DynamicVC()
            show(controller, sender: sender)
    }

In the new UIViewController I'm using this code for creation of the new UIView:

override func loadView() {

        view = UIView()
        view.backgroundColor = .lightGray
}

In result I have view with .lightGray backgroundcolor.

View with lightGray BG

I want to add custom UIView and setup the constraints programmatically, and in result i want UIView with following constraints:

top: 0

bottom:(view.frame.height*0.9)

leading:0

trailing:(view.frame.width*0.15)

width:(view.frame.width*0.85)

height:(view.frame.height*0.1)

Example:

enter image description here

Here is my code:

topMenuView = UIView()
        topMenuView.backgroundColor = .red

        view.addSubview(topMenuView)
        topMenuView.translatesAutoresizingMaskIntoConstraints = false
         setupConstraints(item: topMenuView, topC: 0, topToItem: view, bottomC: (view.frame.height*0.9), bottomToItem: view, widthC: (view.frame.width*0.85), heightC: (view.frame.height*0.1), leadingCon: 0, trailingCon: (view.frame.width*0.15))

I'm using this constructed function for constraints:

 func setupConstraints(item:UIView, topC:CGFloat, topToItem:UIView, bottomC:CGFloat, bottomToItem:UIView, widthC:CGFloat, heightC:CGFloat, leadingCon:CGFloat, trailingCon:CGFloat) {

            let topConstraint = NSLayoutConstraint(item: item, attribute: .top, relatedBy: .equal, toItem: topToItem, attribute: .bottom, multiplier: 1, constant: topC)
            let bottomConstraint = NSLayoutConstraint(item: item, attribute: .bottom, relatedBy: .equal, toItem: bottomToItem, attribute: .top, multiplier: 1, constant: bottomC)
            let widthConstraint = NSLayoutConstraint(item: item, attribute: NSLayoutAttribute.width, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: widthC)
            let heightConstraint = NSLayoutConstraint(item: item, attribute: NSLayoutAttribute.height, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: heightC)

            let leading = NSLayoutConstraint(item: item,attribute: .leading,relatedBy: .equal, toItem: view, attribute: .leadingMargin, multiplier: 1.0, constant: leadingCon)

            let trailing = NSLayoutConstraint(item: item,attribute: .trailing, relatedBy: .equal, toItem: view, attribute: .trailingMargin,multiplier: 1.0,constant: trailingCon)

            view?.addConstraints([topConstraint, bottomConstraint, widthConstraint, heightConstraint, leading, trailing])

            NSLayoutConstraint.activate([topConstraint, bottomConstraint, widthConstraint, heightConstraint, leading, trailing])
        }

But in the result i receive only UIView with gray background, the new UIView with red background doesn't appears.

What I'm doing wrong???

3
  • One thing: only activate the constraints. You should not add them to the view. Commented Nov 22, 2017 at 12:53
  • It is also odd that you are relating .top of one view to .bottom of another and vice versa. Why not .top to .top and .bottom to .bottom? Commented Nov 22, 2017 at 12:54
  • Also, ,call super.loadView() in your overridden loadView method. Commented Nov 22, 2017 at 12:57

1 Answer 1

2

You should only specify bottom OR height and width OR trailing, otherwise you are going to get conflicts here.

see playground:

import PlaygroundSupport
import UIKit

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        let red = UIView()
        red.backgroundColor = .red
        view.addSubview(red)
        red.translatesAutoresizingMaskIntoConstraints = false
        red.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
        red.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
        red.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.85).isActive = true
        red.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.1).isActive = true
    }
}

PlaygroundPage.current.liveView = ViewController()
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.