Question

I am trying to make the Layout using constraints, but I have many custom controls with internal nested Subviews. And I am adding the constraints to the top view (CustomView) but its not lay-outing the subviews properly.

Ex. I have TextFieldWithLabel class which shows the Label on top and below that a UITextField I am creating the instance of TextFieldWithLabel and adding to super view with constraints.

But its not showing the results as expected. though its visible but not placed where I wanted.For this I dont want to change the whole TextFieldWithLabel class foe Auto Layout.

Please Help!

usernameTextField = [[TextFieldWithLabel alloc] initWithFrame:CGRectMake(0, 0, 100, 50) name:@"UserName"];
    [usernameTextField setTranslatesAutoresizingMaskIntoConstraints:NO];
    [superview addSubview:usernameTextField];
    NSLayoutConstraint* myConstraint = [NSLayoutConstraint constraintWithItem:usernameTextField
                                                                    attribute:NSLayoutAttributeCenterY
                                                                    relatedBy:NSLayoutRelationEqual
                                                                       toItem:superview
                                                                    attribute:NSLayoutAttributeCenterY
                                                                   multiplier:1
                                                                     constant:0];

    [superview addConstraint:myConstraint];

    myConstraint = [NSLayoutConstraint constraintWithItem:usernameTextField
                                                attribute:NSLayoutAttributeCenterX
                                                relatedBy:NSLayoutRelationEqual
                                                   toItem:superview
                                                attribute:NSLayoutAttributeCenterX
                                               multiplier:1
                                                 constant:0];
    [superview addConstraint:myConstraint];

Screen shot : Here its not centered and also the text field (RedColor) is also not clickable.the label and the text field are placed inside TextFieldWithLabel. Please Note : the TextFieldWithLabel is subclass of ComponentView and ComponentView is subclass of UIView.So I suspect this may be the issue ? do I need to auto layout the ComponentsView as well. UITextField

Was it helpful?

Solution

Under autolayout your frame sizes will be ignored (the one you use during initWithFrame:). You've specified positioning constraints, but nothing to do with size, therefore your TextFieldWithLabel is positioned at the centre of the screen, with size zero.

The text field and label are still visible because you say you are not using autolayout internally in this control - presumably you do set some frames and autoresizing masks inside there. The text field and label are therefore outside the bounds of the TextFieldWithLabel, so they are visible, but probably don't respond to touches.

To solve this problem you have two options:

  • Use autolayout internally - for example, if you have this constraint (in VFL) then it will automatically give a height to your control: "V:|-[label]-[textField]-|"
  • Add sizing constraints to your code above - use the same dimensions you did in your initWithFrame. Here is one for setting the height:

    [NSLayoutConstraint constraintWithItem:usernameTextField 
                                 attribute:NSLayoutAttributeHeight 
                                 relatedBy:NSLayoutRelationEqual 
                                    toItem:nil 
                                 attribute:NSLayoutAttributeNotAnAttribute 
                                multiplier:0.0 
                                  constant:50.0];
    

I have a category on UIView to simplify the creation of common constraints here. Using the category code you'd do centerInView: and constrainToSize:

OTHER TIPS

If you don't want your label (or other subviews) to have resizing constraints then...

    self.YourLabel.translatesAutoresizingMaskIntoConstraints = NO;

not sure how you deal with that TextFieldWithLabel, it might not be clear to me that it is actually a UIView subclass (I always name UIView subclasses ending on View)

In that case you ended up with a sneaky View that got in between when building your app. In InterfaceBuilder, you dragged in a View, and probably set the class to "TextFieldWithLabel_View_". You did the usual 'custom contraints' If, however that "TextFieldWithLabel_View_" class has subclassed from a UIView, you introduced an intermediate layer.

In the XIB or Code where you layout the label and the textfield you probably have setup the right constraints relativly to the UIView of your own subclass.

The problem is, that the constraints of the subclassed UIView are not linked to the View that has been dragged in with your StoryBoard.

here is what I did:

@interface TextFieldWithLabel__View__ ()
@property (strong, nonatomic) IBOutlet UIView *backgroundView;
@property (weak, nonatomic) IBOutlet UILabel *labelText;
....
....
@end



-(id)initWithCoder:(NSCoder *)decoder{
    if ((self = [super initWithCoder:decoder])){
        [self addSubview:[[[NSBundle mainBundle] loadNibNamed:@"TextFieldWithLabel__View__" owner:self options:nil] objectAtIndex:0]];
    }

    // Set the backgroundView (the one needed for the IB to create a UIView for XIB)
    // Left, Right, Top and Bottom to 0

    _backgroundView.translatesAutoresizingMaskIntoConstraints = NO;
    [self addConstraint:[NSLayoutConstraint constraintWithItem:_backgroundView
                                                     attribute:NSLayoutAttributeLeft
                                                     relatedBy:NSLayoutRelationEqual
                                                        toItem:self
                                                     attribute:NSLayoutAttributeLeft
                                                    multiplier:0
                                                      constant:0
                         ]
     ];
    [self addConstraint:[NSLayoutConstraint constraintWithItem:_backgroundView
                                                     attribute:NSLayoutAttributeRight
                                                     relatedBy:NSLayoutRelationEqual
                                                        toItem:self
                                                     attribute:NSLayoutAttributeRight
                                                    multiplier:1
                                                      constant:0
                         ]
     ];
    [self addConstraint:[NSLayoutConstraint constraintWithItem:_backgroundView
                                                     attribute:NSLayoutAttributeTop
                                                     relatedBy:NSLayoutRelationEqual
                                                        toItem:self
                                                     attribute:NSLayoutAttributeTop
                                                    multiplier:0
                                                      constant:0
                         ]
     ];
    [self addConstraint:[NSLayoutConstraint constraintWithItem:_backgroundView
                                                     attribute:NSLayoutAttributeBottom
                                                     relatedBy:NSLayoutRelationEqual
                                                        toItem:self
                                                     attribute:NSLayoutAttributeBottom
                                                    multiplier:1
                                                      constant:0
                         ]
     ];
    return self;
}

Now, the moment you want to redisgn the CustomView, drag items around, resize the allocated area or whatever, it nicely will pass through the constraints form that CustomView to your TextFieldWithLabel_View_

And tick of "AutoResize Subviews" in the Storyboard

Hope that helps.

P.S. Don't giveup on AutoLayout... Master it!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top