I have a UIScrollView with 2 subviews. I would like one subview to be “aligned aligned” (left justified), where its leading edge connects to the leading edge of the scrollview. I would like the other subview to be “top-aligned” (right-aligned), where its trailing edge connects to the trailing edge of scrollview.
For some reason, autolayout unexpectedly places the second, involuntarily aligned subview outside the scrollview, on the leading (left) side of the other subview, so that the trailing edge of the subview is aligned with the rising edge of the scrollview.
I am trying to do this programmatically. The code is below. I use 2 shortcuts for 2 subzones. The alpha label is correctly aligned, but the beta label does not align in length as it should.
This also happens if I try to use left and right alignment, and not as leading and ending. The right-aligned label appears in the same wrong place as the label with the aligned end.
I read iOS 6 release notes and answers here and elsewhere many times, and I just don't know why this is happening.
In the view controller:
- (void) viewDidLoad { [super viewDidLoad]; // Create and configure the scroll view. UIScrollView * scrollView = [[UIScrollView alloc] init]; [scrollView setTranslatesAutoresizingMaskIntoConstraints:NO]; // For debugging. [scrollView setClipsToBounds:NO]; scrollView.layer.borderColor = [UIColor redColor].CGColor; scrollView.layer.borderWidth = 1.0; [[self view] addSubview:scrollView]; // Layout scrollview. // Horizontal: leading edge to superview leading edge, with indent. [self.view addConstraint:[NSLayoutConstraint constraintWithItem:scrollView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeading multiplier:1.0 constant:20.0]]; // Horizontal: trailing edge to superview trailing edge, with indent. [self.view addConstraint:[NSLayoutConstraint constraintWithItem:scrollView attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTrailing multiplier:1.0 constant:-20.0]]; // Vertical: top edge to superview top edge, with indent. [self.view addConstraint:[NSLayoutConstraint constraintWithItem:scrollView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1.0 constant:20.0]]; // Vertical: bottom edge to superview bottom edge, with indent. [self.view addConstraint:[NSLayoutConstraint constraintWithItem:scrollView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:1.0 constant:-20.0]]; // Create and configure first label which should be leading-aligned with scrollview. UILabel * labelAlpha = [[UILabel alloc] init]; [labelAlpha setTranslatesAutoresizingMaskIntoConstraints:NO]; [labelAlpha setText:@"Alpha"]; [scrollView addSubview:labelAlpha]; // Layout first label. // Horizontal: leading edge to scrollview leading edge. [scrollView addConstraint:[NSLayoutConstraint constraintWithItem:labelAlpha attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:scrollView attribute:NSLayoutAttributeLeading multiplier:1.0 constant:0.0]]; // Vertical: top edge to scrollview top edge. [scrollView addConstraint:[NSLayoutConstraint constraintWithItem:labelAlpha attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:scrollView attribute:NSLayoutAttributeTop multiplier:1.0 constant:0.0]]; // Create and configure second label which should be trailing-aligned with scrollview. UILabel * labelBeta = [[UILabel alloc] init]; [labelBeta setTranslatesAutoresizingMaskIntoConstraints:NO]; [labelBeta setText:@"Beta"]; [scrollView addSubview:labelBeta]; // Layout second label. // Horizontal: trailing edge to scrollview trailing edge. [scrollView addConstraint:[NSLayoutConstraint constraintWithItem:labelBeta attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:scrollView attribute:NSLayoutAttributeTrailing multiplier:1.0 constant:0.0]]; // Vertical: top edge to scrollview top edge. [scrollView addConstraint:[NSLayoutConstraint constraintWithItem:labelBeta attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:scrollView attribute:NSLayoutAttributeTop multiplier:1.0 constant:0.0]]; }
For reference, exiting a view controller from a recursiveDescription view supports misalignment:
2013-07-15 22:04:23.892 Middleman[5669:907] <UIView: 0x20872960; frame = (0 0; 320 480); transform = [0, -1, 1, 0, 0, 0]; autoresize = RM+BM; layer = <CALayer: 0x20871e60>> | <UIScrollView: 0x208718a0; frame = (20 20; 440 280); gestureRecognizers = <NSArray: 0x20871f20>; layer = <CALayer: 0x208728e0>; contentOffset: {0, 0}> | | <UILabel: 0x20872ab0; frame = (0 0; 44 21); text = 'Alpha'; clipsToBounds = YES; userInteractionEnabled = NO; layer = <CALayer: 0x20872b90>> | | <UILabel: 0x208730e0; frame = (-36 0; 36 21); text = 'Beta'; clipsToBounds = YES; userInteractionEnabled = NO; layer = <CALayer: 0x20873170>>