Henrik Perrochon
Henrik Perrochon

Reputation: 347

iOS - Positioning programmatically a UIImageView inside a UITextField with auto layout

I want to programmatically add an image view (checkmark) as a subview of one textfield. Since I'm using autolayout with all my views, I want to use constraints for positioning this subview. Here is the code:

class UIFormTextField: UITextField {

    lazy var checkMarkView = UIImageView(image: UIImage(named: "BarButtonItemCheck"))

    func setCheckMarkView() {
        self.addSubview(checkMarkView)
        self.addConstraints([
            NSLayoutConstraint(item: checkMarkView, attribute: .CenterY, relatedBy: .Equal, toItem: self, attribute: .CenterY, multiplier: CGFloat(1), constant: CGFloat(0)),
            NSLayoutConstraint(item: checkMarkView, attribute: .Trailing, relatedBy: .Equal, toItem: self, attribute: .Trailing, multiplier: CGFloat(1), constant: -UIStyle.Size.standardHorizontalSpacing)
            ])
    }
}

I call setCheckMarkView in the viewDidLoad function but it does not work. I got an alert: "Probably at least one of the constraints in the following list is one you don't want."

Here is the list, though I don't see why other constraints should interfere with a new view.

"<NSAutoresizingMaskLayoutConstraint:0x15084acf0 h=--& v=--& UIImageView:0x15089f4d0.midX == + 12>",
"<NSAutoresizingMaskLayoutConstraint:0x14f691d70 h=--& v=--& H:[UIImageView:0x15089f4d0(24)]>",
"<NSLayoutConstraint:0x1509c54e0 H:[Bruce.UIFormTextField:0x150895520]-(0)-|   (Names: '|':Bruce.UIForm:0x150998430 )>",
"<NSLayoutConstraint:0x1509a6120 H:|-(0)-[Bruce.UIFormTextField:0x150895520]   (Names: '|':Bruce.UIForm:0x150998430 )>",
"<NSLayoutConstraint:0x14f593e20 H:[Bruce.UIForm:0x150998430]-(0)-|   (Names: '|':UIView:0x1509c92d0 )>",
"<NSLayoutConstraint:0x150950f10 H:|-(0)-[Bruce.UIForm:0x150998430]   (Names: '|':UIView:0x1509c92d0 )>",
"<NSLayoutConstraint:0x14f6143b0 UIView:0x1509c92d0.width == UIView:0x15094e8f0.width>",
"<NSLayoutConstraint:0x150813210 UIImageView:0x15089f4d0.trailing == Bruce.UIFormTextField:0x150895520.trailing - 20>",
"<NSLayoutConstraint:0x150896350 'UIView-Encapsulated-Layout-Width' H:[UIView:0x15094e8f0(320)]>"

Thanks for the help,

Upvotes: 0

Views: 1079

Answers (1)

Lneuner
Lneuner

Reputation: 1100

The problem is that you need to disable the translatesAutoresizingMaskIntoConstraints property on the imageView. This is why you see "NSAutoresizingMaskLayoutConstraint" problems with the constraints

The updated code:

lazy var checkMarkView: UIImageView = {
    let imageView = UIImageView(image: UIImage(named: "BarButtonItemCheck"))
    imageView.translatesAutoresizingMaskIntoConstraints = false
    return imageView
}()

Edit: You don't actually need to disable the property where you declare the checkMarkView. You can also do it in your function "setCheckMarkView" i.e.

func setCheckMarkView() {
    checkMarkView.translatesAutoresizingMaskIntoConstraints = false
    self.addSubview(checkMarkView)
    self.addConstraints([
        NSLayoutConstraint(item: checkMarkView, attribute: .CenterY, relatedBy: .Equal, toItem: self, attribute: .CenterY, multiplier: CGFloat(1), constant: CGFloat(0)),
        NSLayoutConstraint(item: checkMarkView, attribute: .Trailing, relatedBy: .Equal, toItem: self, attribute: .Trailing, multiplier: CGFloat(1), constant: -UIStyle.Size.standardHorizontalSpacing)
        ])
}

Upvotes: 3

Related Questions