AutoLayout for a Dynamic number of Views - ios

I have a UIView at the bottom of a UIViewController that can have a different number of views added.
NSUInteger letterCount = [word length];
NSLog(#"The word letter count is: %ld",(unsigned long)letterCount);
for (int i = 0; i < letterCount; i++) {
NSLog(#"new view being created");
UIView *letterTileView = [UIView autolayoutView];
letterTileView.tag = 600 + i;
[self.bottomBarView addSubview:letterTileView];
}
The word could be any word and therefore have a different number of letters. If the word is APPLE it would create 5 subviews in the bottom bar view.
I would like to use Auto Layout to layout these views. Each view should be 48x48 (height x width). I would like these subviews to be centered in the bottom bar view and have padding in between them.
I have used the following method to setup AL before but unsure how to approach the dynamic situation and laying these out correctly.
+ (NSArray *)constraintsWithVisualFormat:(NSString *)format options:(NSLayoutFormatOptions)opts metrics:(NSDictionary *)metrics views:(NSDictionary *)views

Here's an example from my book, where I generate a bunch of UILabels programmatically and add constraints to them as I go along. It's not the same as your situation (my labels are arranged vertically) but it shows how easy it is to add constraints as you are creating interface dynamically:
UILabel* previousLab = nil;
for (int i=0; i<30; i++) {
UILabel* lab = [UILabel new];
// lab.backgroundColor = [UIColor redColor];
lab.translatesAutoresizingMaskIntoConstraints = NO;
lab.text = [NSString stringWithFormat:#"This is label %d", i+1];
[v addSubview:lab];
[v addConstraints:
[NSLayoutConstraint constraintsWithVisualFormat:#"H:|-(10)-[lab]"
options:0 metrics:nil
views:#{#"lab":lab}]];
if (!previousLab) { // first one, pin to top
[v addConstraints:
[NSLayoutConstraint constraintsWithVisualFormat:#"V:|-(10)-[lab]"
options:0 metrics:nil
views:#{#"lab":lab}]];
} else { // all others, pin to previous
[v addConstraints:
[NSLayoutConstraint
constraintsWithVisualFormat:#"V:[prev]-(10)-[lab]"
options:0 metrics:nil
views:#{#"lab":lab, #"prev":previousLab}]];
}
previousLab = lab;
}

What I've done in the past is create the visual format string dynamically based on the number of views you'll have. Some sample code:
NSArray *views = #[view1, view2, view3]; // this would be a dynamic array with views
NSMutableString *vflString = [NSMutableString string];
NSMutableDictionary *viewsDictionary = [NSMutableDictionary dictionary];
for (int i = 0; i < [views count]; i++) {
NSString *viewIdentifier = [NSString stringWithFormat:#"view%d", i];
[vflString appendString:[NSString stringWithFormat:#"-[%#]-", viewIdentifier];
viewsDictionary[viewIdentifier] = views[i];
}
NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:vflString options:0 metrics:nil views:viewsDictionary];
[self.view addConstraints:constraints];
You can change metrics and positioning and stuff like that too, of course.

Related

Adding programatically created views into scrollview vertically (Linear layout in iOS)

I want to add programatically created UIViews into scrollView with auto layout constraints. Like vertical linear layout in Android.
(In objective c not swift)
I have scrollview inside view controller in storyboard. So basically i want to create and add several views in vertical layout with no spaces into that scrollview. And i want to set container size of the scroll view dynamically according to the view heights.
Each view has label inside and each view needs to set its height dynamically according to text size. But probably i need to come to that later.
for (int i=0; i<10; i++)
{
UIView *viewOne = UIView.new;
[viewOne setTranslatesAutoresizingMaskIntoConstraints:NO];
viewOne.backgroundColor = [UIColor redColor];
NSDictionary *viewsDictionary = #{#"viewOne" : viewOne};
NSDictionary *metricsDictionary = #{#"horizontalSpacing" : #10};
[self.scrollview addSubview:viewOne];
NSArray *horizontalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:#"H:|-horizontalSpacing-[viewOne]-horizontalSpacing-|"
options:NSLayoutFormatDirectionLeadingToTrailing
metrics:metricsDictionary
views:viewsDictionary];
NSArray *const_Height = [NSLayoutConstraint constraintsWithVisualFormat:#"V:[viewOne(50)]"
options:0
metrics:nil
views:viewsDictionary];
[viewOne addConstraints:const_Height];
[self.scrollview addConstraints:horizontalConstraints];
}
With that code i can add views but i need to add one under the other.
In case of using AutoLayout in the context of a UIScrollView I would recommend using a ContentView insider your UIScrollView. Just add them to the ViewControllers View inside the viewDidLoad function.
#interface YourViewController ()
#property (nonatomic, strong) UIScrollView *dataScrollView;
#property (nonatomic, strong) UIView* contentView;
#end
#implementation YourViewController
#synthesize dataScrollView, contentView;
- (void) viewDidLoad {
[super viewDidLoad];
dataScrollView = [[UIScrollView alloc] init];
contentView = [[UIView alloc] init];
// adding the Views programmatically to the hierarchy
[self.view addSubview:dataScrollView];
[dataScrollView addSubview:contentView];
// don't translate the AutoresizingMask into constraints
dataScrollView.translatesAutoresizingMaskIntoConstraints = NO;
contentView.translatesAutoresizingMaskIntoConstraints = NO;
// backgroundColor as you wish?
dataScrollView.backgroundColor = [UIColor clearColor];
contentView.backgroundColor = [UIColor clearColor];
[dataScrollView setScrollEnabled:YES];
[dataScrollView setAlwaysBounceVertical:YES];
NSDictionary* viewsDictionary = NSDictionaryOfVariableBindings(dataScrollView, contentView);
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|[dataScrollView]|" options:0 metrics: 0 views:viewsDictionary]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|[dataScrollView]|" options:0 metrics: 0 views:viewsDictionary]];
[dataScrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|[contentView(==dataScrollView)]|" options:0 metrics: 0 views:viewsDictionary]];
[dataScrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|[contentView]|" options:0 metrics: 0 views:viewsDictionary]];
// see below
// [self setUpViews];
}
This Code will do the Trick for one single view. Add your required Views as Subview to the contentView and set the Constraints.
- (void) setUpViews {
UILabel* testLabel = [[UILabel alloc] init];
[testLabel setText:#"Lorem Ipsum"];
testLabel.translatesAutoresizingMaskIntoConstraints = NO;
[contentView addSubview: testLabel];
// clean up your code with this metrics Dictionary
NSDictionary *metrics = #{#"margintop": #40,
#"marginleft": #10,
#"marginright": #10,
#"marginbottom": #20}
// the Views we want to layout with Constraints
NSDictionary *viewsDictionary = #{
#"contentView":contentView,
#"dataScrollView":dataScrollView,
#"testLabel": testLabel}
// Horizontal (testlabel)
[contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|-marginleft-[testLabel]-marginright-|" options:0 metrics: metrics views:viewsDictionary]];
// Vertical
[contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|-margintop-[testLabel]-marginbottom-|" options:0 metrics: metrics views:viewsDictionary]];
}
Referring to your question of adding multiple Views in a for-loop, there are a lot of possible ways. This could be the easiest solution with constraintsWithVisualFormat.
- (void) setUpViews {
NSDictionary *metrics = #{#"margintop": #40,
#"marginleft": #10,
#"marginright": #10,
#"marginbottom": #20,
};
// Alsways like to have contentView and DataScrollView here
NSMutableDictionary* dictViews = [[NSMutableDictionary alloc] initWithDictionary:#{#"contentView":contentView,
#"dataScrollView":dataScrollView}];
// Basic Leading-String for Vertical Constraints
NSString* verticalConstraintsString = #"V:|-margintop-";
for (NSUInteger index = 0; index < 10; index++) {
// Do your Magic here & add your View
UILabel* testLabel = [[UILabel alloc] init];
[testLabel setText:#"Lorem Ipsum"];
testLabel.translatesAutoresizingMaskIntoConstraints = NO;
[contentView addSubview: testLabel];
// Add to global Mutable Views-Dictionary dictViews
[dictViews setObject:testLabel forKey:[NSString stringWithFormat:#"testLabel%lu", (unsigned long)index]];
// add "[testlabel1]" to the vertical Constraints
verticalConstraintsString = [NSString stringWithFormat:#"%#[testLabel%lu]-", verticalConstraintsString, (unsigned long)index];
// Add Horizontal Constraints
[contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:[NSString stringWithFormat:#"H:|-marginleft-[testLabel%lu]-marginright-|", (unsigned long)index] options:0 metrics: metrics views:#{#"testLabel-%lu":testLabel}]];
}
// Trailing-String
verticalConstraintsString = [NSString stringWithFormat:#"%#marginbottom-|", verticalConstraintsString];
NSDictionary *viewsDictionary = [[NSDictionary alloc] initWithDictionary:dictViews];
// finally adding the vertical Constraints
[contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:verticalConstraintsString options:0 metrics: metrics views:viewsDictionary]];
}
I hope this will help you to get your Views right.

Layout constraints for dynamically created buttons

I am trying to create a view with dynamically created buttons. I am finding it difficult to set the constraints for inner objects other than first one that's created. Where is the issue?
Create & Add buttons to view
-(void) createButton:(NSString *) btnText isButton:(BOOL) type phraseWidth:(NSInteger) width view:(UIView *) currentView {
if (!type) { // if it's a button then create label & button at same place else only create button
// align left to prev button, align baseline
if (prevX == 5) { // button left aligned to rowView, right align none
UIButton *btnView = [[UIButton alloc] init];
btnView.translatesAutoresizingMaskIntoConstraints=NO;
[currentView addSubview:btnView];
NSDictionary *dictScrollConst = NSDictionaryOfVariableBindings(btnView);
NSString *hConstraint = [NSString stringWithFormat:#"H:|-%f-[btnView]|",prevX];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:hConstraint options:0 metrics:nil views:dictScrollConst]];
NSString *vConstraint = #"V:|[btnView]|";
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:vConstraint options:0 metrics:nil views:dictScrollConst]];
prevObject = btnView;
}
else { // align new button to previous button
UIButton *btnView = [[UIButton alloc] init];
btnView.translatesAutoresizingMaskIntoConstraints=NO;
[currentView addSubview:btnView];
NSDictionary *dictScrollConst = NSDictionaryOfVariableBindings(prevObject,btnView);
NSString *hConstraint = [NSString stringWithFormat:#"H:[prevObject]-%d-[btnView]",kHorizontalSidePadding];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:hConstraint options:0 metrics:nil views:dictScrollConst]];
NSString *vConstraint = #"V:|[btnView]|";
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:vConstraint options:0 metrics:nil views:dictScrollConst]];
}
}
}
Doesn't allow constraint to be added with respect to previous button created. Throws up exception:
Impossible to set up layout with view hierarchy unprepared for constraint
There's still way too much code for me to work out what's going on, but this much is obvious:
NSString *vConstraint = #"V:|[btnView]|";
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:vConstraint options:0 metrics:nil views:dictScrollConst]];
[currentView addSubview:btnView];
Those lines are in the wrong order. You cannot add a constraint involving a view (here, btnView) at a time when that view is not in the view hierarchy. (That is exactly what the error message is telling you, though granted it phrases it in rather coy terminology.)
So, add the subview. Then add the constraint that affects it.
What I suggest you do is what I always do: start very simple and work your way up to the full extent of the actual problem. So, I suggest as an exercise that you begin with the second row of your layout, and see if you can do just this simple exercise: given the array of titles #[#"Yellow", #"Purple", #"Blue", #"Red"], can you use it to generate four buttons horizontally?
Here's my code for doing that. Notice how clear and simple it is - ruthlessly logical, spare, and plain. We can always add tweaks later, but this is the kind of simplicity you need to try to maintain and build upon, so that you don't confuse yourself:
NSArray* titles = #[#"Yellow", #"Purple", #"Blue", #"Red"];
UIView* previousButton = nil;
for (NSInteger i = 0; i < 4; i++) {
UIButton* b = [UIButton buttonWithType:UIButtonTypeSystem];
[b setTitle:titles[i] forState:UIControlStateNormal];
[b setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.view addSubview:b];
[self.view addConstraints:
[NSLayoutConstraint constraintsWithVisualFormat:#"V:|-(100)-[b]"
options:0 metrics:nil views:#{#"b":b}]];
if (i == 0) {
[self.view addConstraints:
[NSLayoutConstraint constraintsWithVisualFormat:#"H:|-(50)-[b]"
options:0 metrics:nil views:#{#"b":b}]];
} else {
[self.view addConstraints:
[NSLayoutConstraint constraintsWithVisualFormat:#"H:[p]-(20)-[b]"
options:0 metrics:nil views:#{#"b":b, #"p":previousButton}]];
}
previousButton = b;
}
Given this, we see at once one of the things wrong with your code: there is no evidence that you are setting the previous button (your prevObject) on any except the first pass, when of course you need to do it on every pass.
Once we have code that works, we can start to modify it to approach what you are wishing to do. For example, it is now easy to change the hard-coded spacing to use variables like yours instead:
NSArray* titles = #[#"Yellow", #"Purple", #"Blue", #"Red"];
UIView* previousButton = nil;
NSInteger initialX = 5; // *
NSInteger horizSpace = 10; // *
for (NSInteger i = 0; i < 4; i++) {
UIButton* b = [UIButton buttonWithType:UIButtonTypeSystem];
[b setTitle:titles[i] forState:UIControlStateNormal];
[b setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.view addSubview:b];
[self.view addConstraints:
[NSLayoutConstraint constraintsWithVisualFormat:#"V:|-(100)-[b]"
options:0 metrics:nil views:#{#"b":b}]];
if (i == 0) {
[self.view addConstraints:
[NSLayoutConstraint constraintsWithVisualFormat:#"H:|-(initialX)-[b]"
options:0 metrics:#{#"initialX":#(initialX)} views:#{#"b":b}]];
} else {
[self.view addConstraints:
[NSLayoutConstraint constraintsWithVisualFormat:#"H:[p]-(horizSpace)-[b]"
options:0 metrics:#{#"horizSpace":#(horizSpace)} views:#{#"b":b, #"p":previousButton}]];
}
previousButton = b;
And so forth. The point is: This is how I "grow my code", starting always with the simple and evolving, making sure it works at every iteration, until I reach the thing I'm really trying to do. Go ye and do likewise!

Vertically stack an array of buttons using auto layout VFL

I'm learning auto layout and I'd like to setup a set of buttons to be vertically stacked and evenly spaced. I'd also like the buttons pinned to the bottom of the view. What's a good way to setup these constraints with VFL? The button list will be passed in as an array of UIButtons.
NSArray *buttons = [button1, button2, button3, button4, ...]
NSMutableArray *allConstraints = [NSMutableArray array]
UIButton *previousButton;
for (UIButton button in buttons) {
// Buttons take up full width
NSArray *constraints = [NSLayoutConstraint
constraintsWithVisualFormat:#"H:|[button]|"
options:0
metrics:nil
views:NSDictionaryOfVariableBindings(button);];
[allConstraints addObjectsFromArray:constraints];
constraints = [NSLayoutConstraint
constraintsWithVisualFormat:#"V:|[button]|"
options:0
metrics:nil
views:NSDictionaryOfVariableBindings(button);];
[allConstraints addObjectsFromArray:constraints];
if (!previousButton) {
NSDictionary *metrics = #{#"padding" : #(10)};
// Make buttons height
constraints = [NSLayoutConstraint constraintsWithVisualFormat:#"V:[-(padding)-previousButton(==button)]"
options:0
metrics:metrics
views:NSDictionaryOfVariableBindings(previousButton, button)];
[allConstraints addObjectsFromArray:constraints];
}
previousButton = button;
}
[self.view addConstraints:allConstraints]
This doesn't achieve what I need as the buttons don't get pinned to the bottom of the view.
I would do it in a somewhat different way. Rather than building up the constraints inside a loop, I would build the format string in a loop.
-(void)addButtonsWithConstraints:(NSArray *) buttons {
NSMutableDictionary *views = [NSMutableDictionary new];
for (int i = 0; i<buttons.count; i++) {
[buttons[i] setTranslatesAutoresizingMaskIntoConstraints: NO];
[self.view addSubview:buttons[i]];
[views setObject:buttons[i] forKey:[NSString stringWithFormat:#"button%d",i]];
}
NSMutableString *formatString = [#"V:" mutableCopy];
for (int i = 0; i<buttons.count-1; i++) {
[formatString appendFormat:#"[button%d]-10-", i];
}
[formatString appendFormat:#"[button%lu]|", buttons.count - 1]; // pins the last button to the bottom of the view
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:formatString options:NSLayoutFormatAlignAllLeft | NSLayoutFormatAlignAllRight metrics:nil views:views]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"|[button0]|" options:0 metrics:nil views:views]];
}
The last line sets button0 to the full width of the view, and the format options in the previous line make all the buttons align their left and right edges.
Hi this might help you out
NSArray *buttons = #[button1, button2, button3, button4, button5];
NSMutableArray *allConstraints = [NSMutableArray array];
UIButton *previousButton;
for (UIButton *button in buttons) {
[button setTranslatesAutoresizingMaskIntoConstraints:NO];
// Buttons take up full width
NSArray *constraints = [NSLayoutConstraint
constraintsWithVisualFormat:#"H:|[button]|"
options:0
metrics:nil
views:NSDictionaryOfVariableBindings(button)];
[allConstraints addObjectsFromArray:constraints];
if (!previousButton) {
constraints = [NSLayoutConstraint
constraintsWithVisualFormat:#"V:|->=10-[button(65)]"
options: 0
metrics:nil
views:NSDictionaryOfVariableBindings(button)];
[allConstraints addObjectsFromArray:constraints];
}
if (previousButton) {
NSDictionary *metrics = #{#"padding" : #(10)};
// Make buttons height
constraints = [NSLayoutConstraint constraintsWithVisualFormat:#"V:[previousButton]-(20)-[button(65)]"
options:0
metrics:metrics
views:NSDictionaryOfVariableBindings(previousButton, button)];
[allConstraints addObjectsFromArray:constraints];
}
previousButton = button;
}
NSArray *constraints = [NSLayoutConstraint
constraintsWithVisualFormat:#"V:[previousButton]-10-|"
options:0
metrics:nil
views:NSDictionaryOfVariableBindings(previousButton)];
[allConstraints addObjectsFromArray:constraints];
[self.view addConstraints:allConstraints]

View with two positions using AutoLayout

I have a list of views that I want to position. I have two states where the views should be positioned differently.
I am new to AutoLayout and I might be accessing this the wrong way - I am open to different ways of doing this.
I have created this to position a list of TabBarItem : UIView for the first state:
NSMutableDictionary* metrics = [#{#"margin": #(TAB_BAR_ITEM_MARGIN)} mutableCopy];
for (int i = 0; i < [self.tabBarItems count]; i++)
{
TabBarItem* item = [self.tabBarItems objectAtIndex:i];
if (i > 0)
{
TabBarItem* lastAddedItem = [self.tabBarItems objectAtIndex:i - 1];
NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(item, lastAddedItem);
NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:#"H:[item]-(==margin)-[lastAddedItem]" options:0 metrics:metrics views:viewsDictionary];
[self.view addConstraints:constraints];
}
else
{
NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(item);
NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:#"H:|-(>=0)-[item]-(==margin)-|" options:0 metrics:metrics views:viewsDictionary];
[self.view addConstraints:constraints];
}
NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(item);
NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|-(==0)-[item]" options:0 metrics:metrics views:viewsDictionary];
[self.view addConstraints:constraints];
}
self.view is the superview of the TabBarItems.
Now I want to be able to move all the TabBarItems to completely different position (will probably require different constraints) using AutoLayout.
How should I approach this? Can I identify a constraint and remove it to add another?
As mentioned I am new to AutoLayout and really want to do this the right way :-)
I achieved this by having two NSMutableArrays: One for all the constraints needed in the first position and one for all the constraints needed in the other position. By doing that I was able to remove the active constraints from the first list and then add the new ones from the second list.
Not very elegant, but I couldn't find another way to do it.

Odd autolayout glitch - placing a custom view using autolayout into a superview

I have a very odd problem with auto layout. When I place a simple, ordinary view into a superview and attach constraints to it programmatically, it works exactly as I expect. However, when I do the same thing with a custom view that itself has subviews, the constraints do not work properly.
I set up the custom view's autolayout thus:
- (void) initialiseSubviews
{
self.backgroundColor = [UIColor whiteColor];
UILabel * headerLabel = [[UILabel alloc] initWithFrame:CGRectMake(0.0, 0.0, self.frame.size.width, 20.0)];
headerLabel.backgroundColor = [self tintColor];
[self addSubview:headerLabel];
NSDictionary * viewDict = NSDictionaryOfVariableBindings(headerLabel);
NSArray * horiz = [NSLayoutConstraint constraintsWithVisualFormat:#"H:|-[headerLabel]-|" options:0 metrics:nil views:viewDict];
NSArray * vert = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|-[headerLabel]" options:0 metrics:nil views:viewDict];
NSArray * height = [NSLayoutConstraint constraintsWithVisualFormat:#"V:[headerLabel(20)]" options:0 metrics:nil views:viewDict];
[headerLabel addConstraints:height];
[self addConstraints:horiz];
[self addConstraints:vert];
}
+ (BOOL) requiresConstraintBasedLayout
{
return YES;
}
- (BOOL) translatesAutoresizingMaskIntoConstraints
{
return NO;
}
- (CGSize) intrinsicContentSize
{
return CGSizeMake(200.0, 120.0);
}
...and add that to a content view as follows:
- (SSNodeView *) addNodeAtPoint:(CGPoint)point
{
// Prepare the node view
SSNodeView * nodeView = [SSNodeView nodeView];
[self.gridView addSubview:nodeView];
NSDictionary * viewDict = NSDictionaryOfVariableBindings(nodeView);
NSArray * width = [NSLayoutConstraint constraintsWithVisualFormat:#"H:[nodeView(>=300)]" options:0 metrics:0 views:viewDict];
NSArray * height = [NSLayoutConstraint constraintsWithVisualFormat:#"V:[nodeView(>=200)]" options:0 metrics:0 views:viewDict];
[nodeView addConstraints:width];
[nodeView addConstraints:height];
// Set its autolayout properties
NSDictionary * metricDict = #{#"x":[NSNumber numberWithFloat:point.x], #"y":[NSNumber numberWithFloat:point.y]};
NSArray * horizontal = [NSLayoutConstraint constraintsWithVisualFormat:#"H:|-x-[nodeView]" options:0 metrics:metricDict views:viewDict];
NSArray * vertical = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|-y-[nodeView]" options:0 metrics:metricDict views:viewDict];
[self.gridView addConstraints:horizontal];
[self.gridView addConstraints:vertical];
// Update and layout constraints
[self.gridView layoutIfNeeded];
return nodeView;
}
...and yet, it always appears at its original frame, which is not adjusted for auto layout! If I switch to a plain ordinary UIView and use the exact same layout code it works perfectly, things only go wrong when I add subviews, with or without constraints, to my primary view. It feels like there's something I'm supposed to do to make custom layouts work properly, but I've no idea what it might be.
Anyone got any ideas?
-Ash
Ok, it would seem that there has been a change, and overriding the method for translatesAutoresizingMaskIntoConstraints no longer works as expected; removing that method and setting the property it references fixes at least some of the problems I'm experiencing.

Resources