skip to Main Content

Consider having dynamic (programmatically calculated) size and position for a view.

While I can easily set width and height to a constant, like:

myView.widthAnchor.constraint(equalToConstant: mySize.width)

Where widthAnchor is of NSLayoutDimension type.

But I get compile error for each of below:

myView.leadingAnchor.constraint(equalToConstant: 0.0)
myView.leftAnchor.constraint(equalToConstant: 0.0)

Where leadingAnchor and leftAnchor are both of NSLayoutXAxisAnchor type.

With error message:

No exact matches in call to instance method 'constraint'

Is there any way to have constant X/Y position using constraint(s)?

Notes:

#1 myView is the root-view, without any-other-view, hence something like below is not possible:

myView.leadingAnchor.constraint(equalTo: myOtherView.leadingAnchor, constant: 0.0)

But would not make much sense anyway, as now I would get same error, but while trying to give myOtherView a constant position.

#2 Above code is Swift 5, but I tag Obj-C and Obj-C++ too, as I know those languages, and would understand those answers as well.

Example 2

While a dynamic-position is a general requirement, but to answer comments about why myView is a root-view, see:

myView.translatesAutoresizingMaskIntoConstraints = false;
if #available(iOS 11.0, *) {
    myView.leadingAnchor.constraint(equalTo: myView.safeAreaLayoutGuide.leadingAnchor)
        .isActive = true;

    // ...
} else {
    // Below gives error.
    myView.leadingAnchor.constraint(equalToConstant: 0.0)
        .isActive = true;

    // ...
}

Basically, older iOS versions don’t have safe-area anchor, hence there I need to use a constant.

2

Answers


  1. Chosen as BEST ANSWER

    Here is how I worked-around the limitation:

    extension UIView {
    
    func pinToSafeArea() {
    
    let myView = self;
    if let parent = myView.superview {
        myView.translatesAutoresizingMaskIntoConstraints = false;
        if #available(iOS 11.0, *) {
            myView.leadingAnchor.constraint(equalTo: parent.safeAreaLayoutGuide.leadingAnchor)
                .isActive = true;
    
            // ...
        } else {
            myView.leadingAnchor.constraint(equalTo: parent.leadingAnchor, constant: 0.0)
                .isActive = true;
    
            // ...
        }
    } else {
        // Let's hope magically fills safe-area ;-)
        myView.translatesAutoresizingMaskIntoConstraints = true;
    }
    
    } // func
    
    } // extension
    

  2. I think this method constraint(equalToConstant:) is deprecated or no more available now.

    You can use the like:

    newView.leadingAnchor.constraint(equalTo: oldView.leadingAnchor) //without giving any constant value
    newView.leadingAnchor.constraint(equalTo: oldView.leadingAnchor, constant: 0.0) //with some constant value
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search