vishnuvarthan
vishnuvarthan

Reputation: 512

Autolayout Issue in UIView

I am here to get help for a simple problem.My app runs in both 3.5" and 4" screens but the view is not centred in both the sizes(check images for the view).I am using auto layout and also tried to reset suggested constraints.When i bring the label to centre in one view it is not positioned correctly in the other view.Please help i am stuck

3.5" and 4"

Upvotes: 0

Views: 141

Answers (2)

Zhang
Zhang

Reputation: 11607

Wrap all your subviews except the red grandient background inside a container UIView:

@property (nonatomic, strong) UIView *container;

[self.container addSubview:greyBox];
[self.container addSubview:getStarted];
...

[self.view addSubview:self.redBG];
[self.view addSubview:self.container];

Update your constraints to be relative to your container view instead of self.view.

Then center your container view to your self.view:

// ---------------------------------------------------------------
// centers the container view to your view controller's vivew
// ---------------------------------------------------------------
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.container attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0.0]];

[self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.container attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0.0]];

That way, your subview always appear to be centered.

I think the problem you're having at the moment is that you 'offset' each subview's y position relative to the self.view's top edge. You might get it right on one screen, but then when your screen gets longer, it appears wrong.

Using the above view container method, lets you dynamically add as much subviews as you like and it is still centered, assuming your subviews are connected to the container view's top and bottom edges like a tent.

Floating subviews inside a container view will cause the container to have 0 height and not work.

Update

Not sure how you've setup your IB constraints, you might want to show screenshots of them.

Perhaps you have not setup your constraints properly in IB. Maybe you can improve your constraint settings similar to the ones I've provided below to see if it fixes it.

This is a demo of the method I mentioned above:

4 inch iPhone screen:

4 inch iPhone screenshot

3.5 inch iPhone screen:

3.5 inch iPhone screenshot

Notice how both screenshot shows the white box being centered in the view.

This is the code I used:

Header File

// HEADER FILE
#import <UIKit/UIKit.h>

@interface MainViewController : UIViewController

@property (nonatomic, strong) UIView *gradient;

@property (nonatomic, strong) UIView *container;
@property (nonatomic, strong) UIView *whiteBox;
@property (nonatomic, strong) UILabel *label1;
@property (nonatomic, strong) UIButton *getStarted;
@property (nonatomic, strong) UILabel *label2;

@end

Implementation File

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.

    [self initView];
    [self initConstraints];
}

-(void)initView
{
    self.gradient = [[UIView alloc] init];

    CAGradientLayer *gradientLayer = [CAGradientLayer layer];

    gradientLayer.frame = self.view.frame;

    UIColor *redColor = [UIColor colorWithRed:157.0/255.0 green:37.0/255.0 blue:29.0/255.0 alpha:1.0];
    UIColor *pinkColor = [UIColor colorWithRed:216.0/255.0 green:101.0/255.0 blue:100.0/255.0 alpha:1.0];

    gradientLayer.startPoint = CGPointMake(0.5, 0.0);
    gradientLayer.endPoint = CGPointMake(0.5, 1.0);
    gradientLayer.colors = @[(id)redColor.CGColor,
                             (id)pinkColor.CGColor,
                             (id)redColor.CGColor];

    [self.gradient.layer insertSublayer:gradientLayer atIndex:0];


    // container view
    self.container = [[UIView alloc] init];


    // white box
    self.whiteBox = [[UIView alloc] init];
    self.whiteBox.backgroundColor = [UIColor colorWithRed:0.95 green:0.95 blue:0.95 alpha:1.0];
    self.whiteBox.layer.shadowColor = [UIColor blackColor].CGColor;
    self.whiteBox.layer.shadowOffset = CGSizeMake(0.0, 3.0);
    self.whiteBox.layer.shadowOpacity = 0.5;
    self.whiteBox.layer.shadowRadius = 3.0;

    self.label1 = [[UILabel alloc] init];
    self.label1.text = @"Label 1 Text Goes Here";
    self.label1.textAlignment = NSTextAlignmentCenter;
    self.label1.textColor = redColor;

    self.getStarted = [[UIButton alloc] init];
    [self.getStarted setTitle:@"Get Started" forState:UIControlStateNormal];
    [self.getStarted setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
    self.getStarted.backgroundColor = redColor;

    self.label2 = [[UILabel alloc] init];
    self.label2.text = @"Version 1.3 (log enabled)";
    self.label2.textAlignment = NSTextAlignmentCenter;
    self.label2.textColor = [UIColor darkGrayColor];
    self.label2.font = [UIFont fontWithName:@"Arial" size:14];


    [self.whiteBox addSubview:self.label1];
    [self.whiteBox addSubview:self.getStarted];
    [self.whiteBox addSubview:self.label2];

    [self.container addSubview:self.whiteBox];

    [self.view addSubview:self.gradient];
    [self.view addSubview:self.container];
}

-(void)initConstraints
{
    self.gradient.translatesAutoresizingMaskIntoConstraints = NO;
    self.container.translatesAutoresizingMaskIntoConstraints = NO;
    self.whiteBox.translatesAutoresizingMaskIntoConstraints = NO;
    self.label1.translatesAutoresizingMaskIntoConstraints = NO;
    self.getStarted.translatesAutoresizingMaskIntoConstraints = NO;
    self.label2.translatesAutoresizingMaskIntoConstraints = NO;

    id views = @{
                 @"gradient": self.gradient,
                 @"container": self.container,
                 @"whiteBox": self.whiteBox,
                 @"label1": self.label1,
                 @"getStarted": self.getStarted,
                 @"label2": self.label2
                 };

    // gradient constraint
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[gradient]|" options:0 metrics:nil views:views]];
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[gradient]|" options:0 metrics:nil views:views]];


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

    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.container
                                                          attribute:NSLayoutAttributeCenterY
                                                          relatedBy:NSLayoutRelationEqual
                                                             toItem:self.view
                                                          attribute:NSLayoutAttributeCenterY
                                                         multiplier:1.0
                                                           constant:0.0]];

    // white box constraints

    [self.container addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-10-[whiteBox(280)]-10-|" options:0 metrics:nil views:views]];
    [self.container addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-10-[whiteBox]-10-|" options:0 metrics:nil views:views]];

    // white box subview constraints

    [self.whiteBox addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-10-[label1]-10-|" options:0 metrics:nil views:views]];
    [self.whiteBox addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-10-[getStarted]-10-|" options:0 metrics:nil views:views]];
    [self.whiteBox addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-10-[label2]-10-|" options:0 metrics:nil views:views]];

    [self.whiteBox addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-10-[label1]-20-[getStarted(40)]-15-[label2]-5-|" options:0 metrics:nil views:views]];


}

Upvotes: 0

ArturOlszak
ArturOlszak

Reputation: 2673

You need to add 4 constraints to the view which needs to be centered.

Pin:
1. Width.
2. Height.

Align:
3. Horizontal center in container.
4. Vertical center in container.

Upvotes: 1

Related Questions