narner narner - 2 months ago 15
Objective-C Question

Programmatically using constraints to center a UIIMageView

I'm working on an iOS project in which I need to programmatically use constraints for my views. I'm used to storyboards, but am using xibs for this particular project due to the nature of the project specification.

I have a

MainViewController
, in which I create the following properties in the .h file:

@property (nonatomic, strong) IBOutlet UIImageView *backgroundImageView;
@property (nonatomic, strong) IBOutlet UIImageView *logoImage;


I added these UIImageView instances to my XIB file, and selected the appropriate images via the Attributes inspector.

In my .m file, I have a
addConstraints
method, which is called in
viewDidLoad
. Inside this method, I make sure to turn off converting autoresizingMasks into constraints:

self.backgroundImageView.translatesAutoresizingMaskIntoConstraints = NO;
self.logoImage.translatesAutoresizingMaskIntoConstraints = NO;


Then, I've set up constraints so that the background image takes up the entirety of the superview:

id mainView = @{@"background": self.backgroundImageView};

//Set constraints so that the background takes up the entirety of the superview
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[background]|" options:0 metrics:nil views:mainView]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[background]|" options:0 metrics:nil views:mainView]];


Finally, I set constraints so that the logo view is in the center of the view (which is where I am going wrong):

// Width constraint
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.logoImage
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeWidth
multiplier:0.5
constant:0]];

// Height constraint
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.logoImage
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeHeight
multiplier:0.5
constant:0]];

// Center horizontally
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.logoImage
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeCenterX
multiplier:1.0
constant:0.0]];

// Center vertically
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.logoImage
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeCenterY
multiplier:1.0
constant:0.0]];


The error I receive is
*** +[NSLayoutConstraint constraintWithItem:attribute:relatedBy:toItem:attribute:multiplier:constant:]: Constraint items must each be an instance of UIView or subclass'
, which I don't fully understand, as my constraint items (two
UIImageView
instances) are either subclasses of
UIView
, but I may be misunderstanding this. Can anyone help point out where I'm going wrong?

Answer

Try that :

// Width constraint
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.logoImage
                                                 attribute:NSLayoutAttributeWidth
                                                 relatedBy:NSLayoutRelationEqual
                                                    toItem:self.backgroundImageView
                                                 attribute:NSLayoutAttributeWidth
                                                multiplier:0.5
                                                  constant:0]];

// Height constraint
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.logoImage
                                                 attribute:NSLayoutAttributeHeight
                                                 relatedBy:NSLayoutRelationEqual
                                                    toItem:self.backgroundImageView
                                                 attribute:NSLayoutAttributeHeight
                                                multiplier:0.5
                                                  constant:0]];

// Center horizontally
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.logoImage
                                                 attribute:NSLayoutAttributeCenterX
                                                 relatedBy:NSLayoutRelationEqual
                                                    toItem:self.backgroundImageView
                                                 attribute:NSLayoutAttributeCenterX
                                                multiplier:1.0
                                                  constant:0.0]];

// Center vertically
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.logoImage
                                                 attribute:NSLayoutAttributeCenterY
                                                 relatedBy:NSLayoutRelationEqual
                                                    toItem:self.backgroundImageView
                                                 attribute:NSLayoutAttributeCenterY
                                                multiplier:1.0
                                                  constant:0.0]];

You were trying to define constraints between your UIImageView and your view controller. You must define constraints between views which are subviews of a same view.