Göktuğ Aral
Göktuğ Aral

Reputation: 1409

UIView Display Late If Creating It Programmatically with Auto Layout

I'm stuck! I'm working on a viewController which is going to be a base for other viewControllers. Others will extend from it.

I want to create some view (like custom NavigationBar) with programmatically constraints for baseViewController and I created it.

So I have storyboard, there is a navigationController with a rootViewController (HomeViewController) and this homeViewController extend from baseViewController.

Here is my storyboard looks like;

Storyboard scene

So, my constraints are working! But the view which is created with programmatically constraints display after couple of second and its drive me crazy!

Here is how it looks when app first running;

enter image description here

And after couple of seconds my view appears;

enter image description here

I want to also share my codes. I am using visual format language to create constraints;

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

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark - Initialize BaseView

- (void)initializeBaseView{

    //Background View
    if (self.backgroundContainerView == nil) {
        self.backgroundContainerView = [UIView new];
        self.backgroundContainerView.translatesAutoresizingMaskIntoConstraints = NO;
        [self.view addSubview:self.backgroundContainerView];
        [self.view sendSubviewToBack:self.backgroundContainerView];
    }
    [self initConstraint_1];


    //Navigation Header View
    if(self.navigationBarContainerView == nil){
        self.navigationBarContainerView = [UIView new];
        self.navigationBarContainerView.translatesAutoresizingMaskIntoConstraints = NO;
        [self.navigationBarContainerView setBackgroundColor:[UIColor clearColor]];
        [self.view addSubview:self.navigationBarContainerView];

    }
    [self initConstraint_2];

    if (self.backgroundType==BackgroundTypeWhite) {
        //very light Gray
        [self.backgroundContainerView setBackgroundColor:APP_GRAY_COLOR_ATHENS];
    }

    [self initializeBaseStyle];
}

- (void)initializeBaseStyle{
    [self.navigationBarContainerView setBackgroundColor:[UIColor darkGrayColor]];
}



#pragma mark - Initialize Constraints

- (void)initConstraint_1{
    // 1. Create a dictionary of views
    NSDictionary *viewsDictionary = @{@"firstView":self.backgroundContainerView};
    NSDictionary *metrics = @{@"vSpacing":@0, @"hSpacing":@0};

    // 2. Define the view Position and automatically the Size
    NSArray *constraint_POS_V = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-vSpacing-[firstView]-hSpacing-|"
                                                                        options:0
                                                                        metrics:metrics
                                                                          views:viewsDictionary];

    NSArray *constraint_POS_H = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-hSpacing-[firstView]-hSpacing-|"
                                                                        options:0
                                                                        metrics:metrics
                                                                          views:viewsDictionary];

    [self.view addConstraints:constraint_POS_V];
    [self.view addConstraints:constraint_POS_H];

}


- (void)initConstraint_2{
    NSDictionary *viewsDictionary = @{@"firstView": self.navigationBarContainerView, @"secondView": self.logoImage};
    NSDictionary *metrics = @{@"vSpacing":@74,
                              @"hSpacing":@0,
                              @"BottomSpacing":@60,
                              @"firstViewHeight":@64
                              };


    // 2. Define the view Position and automatically the Size (for the firstView)
    NSArray *constraint_POS_V = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[firstView(firstViewHeight)]"
                                                                        options:0
                                                                        metrics:metrics
                                                                          views:viewsDictionary];

    NSArray *constraint_POS_H = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-hSpacing-[firstView]-hSpacing-|"
                                                                        options:0
                                                                        metrics:metrics
                                                                          views:viewsDictionary];

    [self.view addConstraints:constraint_POS_V];
    [self.view addConstraints:constraint_POS_H];

}

I have plenty of questions;

I hope that's clear. Thank you for your answers and I'm looking forward to hearing from you.

Upvotes: 0

Views: 76

Answers (2)

Mahendra
Mahendra

Reputation: 8904

Call setNeedsLayout and layoutIfNeeded method just after constraints setting. It will work for you.

Upvotes: 0

Ketan Parmar
Ketan Parmar

Reputation: 27428

First if not mandatory then set constraints from IB. If mandatory then perform your task in viewDidAppear and on main thread if required.

Upvotes: 0

Related Questions