iOS layer animation stops abruptly - ios

I am trying to use the animation from this library:
https://github.com/shu223/PulsingHalo
I have a UIScrollView, and within it a UIImageView that has a larger width
UIScrollView *scrollView;
scrollView = [[UIScrollView alloc] init];
scrollView.showsHorizontalScrollIndicator = NO;
scrollView.showsVerticalScrollIndicator = NO;
scrollView.delegate = self;
self.scrollView = scrollView;
[self.view insertSubview:scrollView belowSubview:self.optionsButton];
scrollView.translatesAutoresizingMaskIntoConstraints = NO;
imageView = [[UIImageView alloc] init];
self.mapImageView = imageView;
UIImage* mapImg = [UIImage imageNamed:#"..."];
// Add image (larger than screen size) to the image view.
[imageView setImage: mapImg];
// Set the constraints for the scroll view and the image view.
NSDictionary* viewsDictionary = NSDictionaryOfVariableBindings(scrollView, imageView);
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|[scrollView]|" options:0 metrics: 0 views:viewsDictionary]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|[scrollView]|" options:0 metrics: 0 views:viewsDictionary]];
[scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|[imageView]|" options:0 metrics: 0 views:viewsDictionary]];
[scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|[imageView]|" options:0 metrics: 0 views:viewsDictionary]];
After this, I add a bunch of buttons to my scrollview, programmatically. For instance:
UIButton* flagButton = [UIButton new];
[self.scrollView addSubview: flagButton];
flagButton.translatesAutoresizingMaskIntoConstraints = NO;
NSLayoutConstraint* xc = [NSLayoutConstraint constraintWithItem:flagButton attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.mapImageView attribute:NSLayoutAttributeLeft multiplier:1.f constant:x];
NSLayoutConstraint* yc = [NSLayoutConstraint constraintWithItem:flagButton attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.mapImageView attribute:NSLayoutAttributeTop multiplier:1.f constant:y];
[self.view addConstraints#[xc, yc]];
Now I want to create my halo for this button. I create a specific view for it, centered around my button. I still haven't quite wrapped my head around positioning, so I don't position it for now.
UIView* haloView = [UIView new];
haloView.backgroundColor = [UIColor clearColor];
NSLayoutConstraint* constraintHeight = [NSLayoutConstraint constraintWithItem:haloView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:flagButton attribute:NSLayoutAttributeHeight multiplier:2.0 constant:0.f];
NSLayoutConstraint* constraintWidth = [NSLayoutConstraint constraintWithItem:haloView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:flagButton attribute:NSLayoutAttributeWidth multiplier:2.0 constant:0.f];
NSLayoutConstraint* constraintCenterX = [NSLayoutConstraint constraintWithItem:haloView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:flagButton attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0.f];
NSLayoutConstraint* constraintCenterY = [NSLayoutConstraint constraintWithItem:haloView attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:flagButton attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0.f];
[self.view insertSubview:haloView belowSubview:flagButton];
haloView.translatesAutoresizingMaskIntoConstraints = NO;
constraintCenterX.active = YES;
constraintCenterY.active = YES;
constraintHeight.active = YES;
constraintWidth.active = YES;
PulsingHaloLayer *halo = [PulsingHaloLayer layer];
[haloView.layer insertSublayer:halo atIndex:0];
halo.radius = 50.0;
halo.haloLayerNumber = 4;
halo.duration = 4.0;
This should normally provide me with the pulsing animation shown in the linked library. And I do get it, somewhat. The behavior is hard to describe, but it appears to start correctly, then abruptly stop when it should loop, then restart again a second later. Basically, it does not seem to loop properly as it should, and I have no idea why.
This is the view hierarchy. The last "UIView" is the one with the Halo layer.
These are the UIView's properties as shown by the debugger.
These are the UIScrollView's properties.
Thank you for your help.

Related

Program Subview's Vertical Spacing to Bottom Constraint

SecondViewController adds a UIView that contains a MKMapView as a subview inside an IBAction method:
if(_tagTwo == 4){
seg2_buttonImg = #"Maps.png";
UIImage *btnImage1 = [UIImage imageNamed:seg2_buttonImg];
[_left_button setImage:btnImage1 forState:UIControlStateNormal];
[_table removeFromSuperview];
[mapVC layoutMapView];
[self.view addSubview:mapVC.view];
return;
}
mapVC is created in ViewDidLoad with mapVC = [[CollectionMapViewController alloc] init];
Edit: new code for adding constraints, taken from #Reinier Melian:
#implementation CollectionMapViewController
#synthesize mapView;
- (void)viewDidLoad
{
if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1) {
//[segmentedControl setBackgroundColor:[UIColor whiteColor]];
//[segmentedControl setBackgroundColor:[UIColor leafletBrown]];
[segmentedControl setBackgroundColor:[UIColor leafletLightBrown]];
segmentedControl.layer.cornerRadius = 5;
}
self.mapView.translatesAutoresizingMaskIntoConstraints = NO;
NSArray * verticalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|[mapView]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(self.mapView)];
NSArray * horizontalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:#"H:|[mapView]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(self.mapView)];
//Add constraints to the Parent
[self.view addConstraints:verticalConstraints];
[self.view addConstraints:horizontalConstraints];
}
CollectionMapViewController.h:
#interface SecondViewController : UIViewController <NSFetchedResultsControllerDelegate, CollectionMapViewControllerDelegate>{
CollectionMapViewController* mapVC;
}
#property (nonatomic, retain) CollectionMapViewController* mapVC;
The problem is that it adds the MKMapView to the top of the screen:
I tried to constrain the MKMapView to the bottom of the screen by adding following code to viewDidLoad of MapViewController
mapView.translatesAutoresizingMaskIntoConstraints = NO;
NSLayoutConstraint *bottom =[NSLayoutConstraint
constraintWithItem:mapView
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeBottom
multiplier:1.0f
constant:0.f];
//Add constraints to the Parent
[self.view addConstraint:bottom];
But it just makes the map go black (or more likely moves it completely off the screen?).
What I am trying to get is this:
I would appreciate any help! Thank you so much!
When you add mapView.translatesAutoresizingMaskIntoConstraints = NO; your map rect size is equal to zero if there are not enough constraints to define the correct frame, that is why you have your screen black, you need define all the constraints needed by your MKMapView
Updated using dynamic height constraints
try with this code
self.mapView.translatesAutoresizingMaskIntoConstraints = NO;
CGFloat mapHeigthValue = self.view.frame.size.height/3; //setting the mapView heigth = 1/3 of view height this is an example
NSArray * verticalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:[NSString stringWithFormat:#"V:[mapView(%f)]|",mapHeigthValue] options:0 metrics:nil views:#{#"mapView":self.mapView}];
NSArray * horizontalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:#"H:|[mapView]|" options:0 metrics:nil views:#{#"mapView":self.mapView}];
//Add constraints to the Parent
[self.view addConstraints:verticalConstraints];
[self.view addConstraints:horizontalConstraints];
In viewDidLoad:
mapView.translatesAutoresizingMaskIntoConstraints = NO;
/*Set width and height of mapview */
NSLayoutConstraint *widthConst = [NSLayoutConstraint constraintWithItem:mapView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:400];
NSLayoutConstraint *heightConst = [NSLayoutConstraint constraintWithItem:mapView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:300];
[self.view addConstraint:widthConst];
[self.view addConstraint:heightConst];
/*creater X and Y constraints for mapview */
NSLayoutConstraint *centreHorizontallyConstraint = [NSLayoutConstraint
constraintWithItem:mapView
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeCenterX
multiplier:1.0
constant:0];
[self.view addConstraint:centreHorizontallyConstraint];
NSLayoutConstraint *bottomConstraint = [NSLayoutConstraint
constraintWithItem:mapView
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeBottom
multiplier:1.0
constant:140];
[self.view addConstraint:bottomConstraint];

Subview vertical align middle in view with auto layout constraints programmatically

I need to locate a subview vertical align middle in a view without hardcode the top value 150 using constraint programmatically. I wish to achieve something like below:
Below is my code so far, Please advise.
import UIKit
class MainViewController: UIViewController {
var viewInner:UIView = UIView()
var viewOuter:UIView = UIView()
override func viewDidLoad() {
super.viewDidLoad()
viewInner.backgroundColor = UIColor.redColor()
viewOuter.backgroundColor = UIColor.purpleColor()
viewOuter.frame = CGRectMake(100, 100, 400, 400)
viewInner.setTranslatesAutoresizingMaskIntoConstraints(false)
let viewsDictionary = ["viewInner":viewInner]
viewOuter.addSubview(viewInner)
self.view.addSubview(viewOuter)
//Add Constraint
var constOuterH = NSLayoutConstraint.constraintsWithVisualFormat("H:|-10-[viewInner(>=200)]-10-|", options: NSLayoutFormatOptions(0), metrics: nil, views: viewsDictionary)
var constOuterV = NSLayoutConstraint.constraintsWithVisualFormat("V:|-150-[viewInner(100)]", options: NSLayoutFormatOptions(0), metrics: nil, views: viewsDictionary)
viewOuter.addConstraints(constOuterH)
viewOuter.addConstraints(constOuterV)
}
}
You need to use the non-visual formatting way of adding constraints:
[self.view addConstraint:[NSlayoutConstraint constraintWithItem:self.viewOuter attribute:NSLayoutAttributeCenterY relateBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterY .......]];
to center align things.
The above type of "relational constraints" (it's what I personally call them) is what I tend to use for specifying relations between two views e.g. center alignment, relative positioning.
Visual Formatting language on the other hand is more useful for pinning views to each other from my own observation.
Here's a demo app:
ViewController.h
#interface ViewController : UIViewController
#property (nonatomic, strong) UIView *outerView;
#property (nonatomic, strong) UIView *innerView;
#property (nonatomic, strong) NSLayoutConstraint *outerViewHeightConstraint;
#end
ViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self initViews];
[self initConstraints];
// change height of outerView after 3 seconds
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self changeHeight];
});
}
-(void)changeHeight
{
self.outerViewHeightConstraint.constant = 150;
[UIView animateWithDuration:1.0 animations:^{
[self.innerView layoutIfNeeded];
[self.view layoutIfNeeded];
}];
}
-(void)initViews
{
self.outerView = [[UIView alloc] init];
self.outerView.backgroundColor = [UIColor purpleColor];
self.innerView = [[UIView alloc] init];
self.innerView.backgroundColor = [UIColor redColor];
[self.outerView addSubview:self.innerView];
[self.view addSubview:self.outerView];
}
-(void)initConstraints
{
self.outerView.translatesAutoresizingMaskIntoConstraints = NO;
self.innerView.translatesAutoresizingMaskIntoConstraints = NO;
id views = #{
#"outerView": self.outerView,
#"innerView": self.innerView
};
// outer view constraints
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:[outerView(300)]" options:0 metrics:nil views:views]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.outerView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0.0]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.outerView attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0.0]];
// give outerView a default height e.g. 300
// note we can animate the height of outerview later using this var
self.outerViewHeightConstraint = [NSLayoutConstraint constraintWithItem:self.outerView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeHeight multiplier:1.0 constant:300.0];
[self.view addConstraint:self.outerViewHeightConstraint];
// inner view constraints
[self.outerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|-10-[innerView]-10-|" options:0 metrics:nil views:views]];
[self.outerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:[innerView(50)]" options:0 metrics:nil views:views]];
[self.outerView addConstraint:[NSLayoutConstraint constraintWithItem:self.innerView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.outerView attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0.0]];
[self.outerView addConstraint:[NSLayoutConstraint constraintWithItem:self.innerView attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self.outerView attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0.0]];
}
After running the app for 3 seconds, you'll see the outer view (purple view) shrink in height while the red inner view remains centered within the purple view and maintains its height.
You can also rotate the view too.

iOS Auto layout Rows

I'm trying to understand auto layout better and I created some static methods that can help me out. Now I'm trying to setup an array of views in like a tableview structure (in rows). This works kinda.
See here my problem:
To achieve this I use this code:
//In the update constraints method
UIView *view1 = [self createView];
view1.backgroundColor = [UIColor redColor];
UIView *view2 = [self createView];
view2.backgroundColor = [UIColor yellowColor];
[self addSubview:view1];
[self addSubview:view2];
[self addConstraints:[DXVFL row:#[view1, view2] inView:self]];
//The row method
+ (NSArray *) row:(NSArray const *)views inView:(UIView const *)superview {
NSMutableArray *constraints = [NSMutableArray new];
CGFloat multiplier = 1.f / [views count];
UIView *prev = nil;
for (UIView *view in views) {
if (!view.hidden) {
[constraints addObject:[NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:superview attribute:NSLayoutAttributeWidth multiplier:1.f constant:0.f]];
[constraints addObject:[NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:superview attribute:NSLayoutAttributeHeight multiplier:multiplier constant:0.f]];
if (prev) {
[constraints addObject:[NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:prev attribute:NSLayoutAttributeBottom multiplier:1.f constant:0.f]];
}
prev = view;
}
}
return [constraints copy];
}
So this part works (I guess). But when I want to split the yellow view again in rows. The views are always added into the top region?
In the update constraints method I do this:
UIView *view1 = [self createView];
view1.backgroundColor = [UIColor redColor];
UIView *view2 = [self createView];
view2.backgroundColor = [UIColor yellowColor];
[self addSubview:view1];
[self addSubview:view2];
UIView *view3 = [self createView];
UIView *view4 = [self createView];
[view2 addSubview:view3];
[view2 addSubview:view4];
[self addConstraints:[DXVFL row:#[view1, view2] inView:self]];
[view2 addConstraints:[DXVFL row:#[view3, view4] inView:view2]];
But I want those two rows in the bottom? What am I doing wrong?
Off the top of my head:
You need to add a constraint to tell it to align the view to the top of the superview. At the moment, you just set the height and width but you don't tell it where to put its top edge.
Try changing your code to this:
if (!prev) {
[constraints addObject:[NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:superview attribute:NSLayoutAttributeTop multiplier:1.f constant:0.f]];
} else {
[constraints addObject:[NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:prev attribute:NSLayoutAttributeBottom multiplier:1.f constant:0.f]];
}

Aligning a UIImageView with Auto Layout

What I want is to add an image as a subview, then align it centered along the X axis and 10 points from the bottom of the superview. I need to use Auto Layout only, and preferably visual formatting language.
- (void)viewDidLoad
{
[super viewDidLoad];
self.imageView = [[UIImageView alloc] initWithFrame:CGRectZero];
[self.imageView setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.imageView setImage:[UIImage imageNamed:#"06-arrow-south"]];
self.imageView.contentMode = UIViewContentModeScaleAspectFit;
[self.view addSubview:self.imageView];
[self addConstraints];
self.imageView.layer.borderColor = [[UIColor redColor] CGColor];
self.imageView.layer.borderWidth = 1.0;
}
- (void)addConstraints {
NSDictionary *viewsDictionary = #{#"arrowImage":self.imageView};
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|-[arrowImage(==40)]-|"
options:0
metrics:nil
views:viewsDictionary]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|-[arrowImage(==40)]-10-|"
options:0
metrics:nil
views:viewsDictionary]];
}
Here's what I'm getting:
V:|-[arrowImage]-10-|
This aligns the image view so that it is the standard length (20pt) from the top of its superview, and 10 from the bottom. What you want is to PIN it to the bottom only:
V:[arrowImage]-10-|
I'm not sure that centering in the superview can be done with visual format, but you can create a single constraint to center it:
[self.view addConstraint:
[NSLayoutConstraint
constraintWithItem:self.imageView
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeCenterX
multiplier:1
constant:0]];
There's no need to set the height or width of the image view; its size will be determined from its content.
So, here's the full code for your addConstraints method:
- (void)addConstraints {
[self.view addConstraint:
[NSLayoutConstraint
constraintWithItem:self.imageView
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeCenterX
multiplier:1
constant:0]];
NSDictionary *viewsDictionary = #{#"arrowImage":self.imageView};
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:[arrowImage]-10-|"
options:0
metrics:nil
views:viewsDictionary]];
}
What you currently doing is saying arrowImage should be the full size of the view minus 20px on left, right and top but be minus 10px from bottom.
The to center on x do the following.
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:arrowImage attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0.0];
Then as #Austin points out remove the need to be minus 8 from top and be minus 10 from the bottom:
V:[arrowImage]-10-|
Btw its minus 20 as default when you connect a sibling view to a parent: (see comment below )
|-[

Using iOS Auto Layout to establish constraints between a child view controller and its parent view

Within my root view controller, I'm adding a child view controller's view as a subview, as follows:
ChildViewController *cvc = [[ChildViewController alloc] init];
[self addChildViewController:cvc];
[self.view addSubview:cvc.view];
[cvc didMoveToParentViewController:self];
and I'd now like to use a NSLayoutConstraint to position the cvc.view within the parent view (self.view), such that cvc.view is positioning 25 pts above the bottom of the parent view. My understanding is that the following should work:
UIView *superview = self.view;
UIView *childview = cvc.view;
NSLayoutConstraint *cn =
[NSLayoutConstraint withItem:childview
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:superview attribute:NSLayoutAttributeBottom
multiplier: 1.0
constant: -25.0];
[superview addConstraint: cn];
But the constraint fails at runtime. I thought initially maybe the autoresizing mask in the child view was causing problems (and following the WWDC 2012 Intro video on auto layout), so I set [childview setTranslatesAutoresizingMaskIntoConstraints:NO], but then the childview simply fails to appear.
What am I doing wrong?
I'm not sure but the following should work, or something very similar:
UIView *superview = self.view;
UIView *childview = cvc.view;
NSDictionary *constrainedViews = NSDictionaryOfVariableBindings(childview);
NSArray *constraints =
[superview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:[childview]-25-|"
options:0
metrics:nil
views:constrainedViews];
If not make sure that you are actually setting a size for the childview, something like:
UIView *superview = self.view;
UIView *childview = cvc.view;
NSDictionary *constrainedViews = NSDictionaryOfVariableBindings(childview);
NSArray *constraints =
[superview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|[childview]|"
options:0
metrics:nil
views:constrainedViews];
Say, to make it fill the width of the view. Or:
UIView *superview = self.view;
UIView *childview = cvc.view;
NSDictionary *constrainedViews = NSDictionaryOfVariableBindings(childview);
NSArray *constraints =
[superview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|-[childview(>100,<304)]-|"
options:0
metrics:nil
views:constrainedViews];
Which means something like childview should have a width bigger than 100 but less than 304 with default margins to the superview. Please note I don't know if the above constraint actually makes sense (e.g. it may just always give you 304 width childview as that would leave default margins), but it serves as an example.
To properly setup and size your child view controller with auto layout do the following:
childView.translatesAutoresizingMaskIntoConstraints = NO;
NSLayoutConstraint *left = [NSLayoutConstraint constraintWithItem:superview attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:childview attribute:NSLayoutAttributeLeft multiplier:1 constant:0];
[self.view addConstraint:left];
NSLayoutConstraint *top = [NSLayoutConstraint constraintWithItem:superview attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:childview attribute:NSLayoutAttributeTop multiplier:1 constant:0];
[self.view addConstraint:top];
NSLayoutConstraint *width = [NSLayoutConstraint constraintWithItem:superview attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:childview attribute:NSLayoutAttributeWidth multiplier:1 constant:0];
[self.view addConstraint:width];
NSLayoutConstraint *height = [NSLayoutConstraint constraintWithItem:superview attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:childview attribute:NSLayoutAttributeHeight multiplier:1 constant:0];
[self.view addConstraint:height];
If you prefer the visual format you can do the following:
childView.translatesAutoresizingMaskIntoConstraints = NO;
NSDictionary *views = #{#"childview": childview};
[superview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"|-0-[childview]-0-|" options:0 metrics:nil views:views]];
[superview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|-0-[childview]-0-|" options:0 metrics:nil views:views]];

Resources