Date pickers selection's overlay not adjusting when screen rotates

35 Views Asked by At

I've got a view with two date pickers set to cover the entire view's height and half a width each, so that they are filling the entire view.

I've then added an overlay to each picker to make the selection more visible, like this:

-(void)drawOverlays {
    if (_overlay1 != nil) {
        [_overlay1 removeFromSuperview];
    }
    if (_overlay2 != nil) {
        [_overlay2 removeFromSuperview];
    }
    _overlay1 = [[UIView alloc] initWithFrame:CGRectMake(_startPicker.bounds.origin.x, (_startPicker.frame.size.height/2)-19, _startPicker.bounds.size.width, 38)];
    _overlay1.backgroundColor = [UIColor redColor];
    _overlay1.alpha = 0.5f;
    [_startPicker addSubview:_overlay1];
    _overlay2 = [[UIView alloc] initWithFrame:CGRectMake(_endPicker.bounds.origin.x, (_endPicker.frame.size.height/2)-19, _endPicker.bounds.size.width, 38)];
    _overlay2.backgroundColor = [UIColor redColor];
    _overlay2.alpha = 0.5f;
    [_endPicker addSubview:_overlay2];
}

I'm calling this method from the -viewDidLayoutSubviews method and from the -viewWillTransitionToSize:withTransitionCoordinator method, and the first time the view appears everything is fine.

Then I rotate my iPad and the overlays are shown inverted, meaning that when in landscape the overlays are the size I want for the portrait and vice versa.

What's wrong with my code?

1

There are 1 best solutions below

0
DonMag On BEST ANSWER

You will be much better off using constraints and letting auto-layout handle the resizing:

-(void)drawOverlays {

    if (_overlay1 != nil) {
        [_overlay1 removeFromSuperview];
    }
    if (_overlay2 != nil) {
        [_overlay2 removeFromSuperview];
    }

    //_overlay1 = [[UIView alloc] initWithFrame:CGRectMake(_startPicker.bounds.origin.x, (_startPicker.frame.size.height/2)-19, _startPicker.bounds.size.width, 38)];

    // instantiate overlay1
    _overlay1 = [UIView new];
    _overlay1.backgroundColor = [UIColor redColor];
    _overlay1.alpha = 0.5f;

    // add as subview of startPicker
    [_startPicker addSubview:_overlay1];

    //_overlay2 = [[UIView alloc] initWithFrame:CGRectMake(_endPicker.bounds.origin.x, (_endPicker.frame.size.height/2)-19, _endPicker.bounds.size.width, 38)];

    // instantiate overlay2
    _overlay2 = [UIView new];
    _overlay2.backgroundColor = [UIColor redColor];
    _overlay2.alpha = 0.5f;

    // add as subview of endPicker
    [_endPicker addSubview:_overlay2];

    // we want to use auto-layout / constraints
    _overlay1.translatesAutoresizingMaskIntoConstraints = NO;
    _overlay2.translatesAutoresizingMaskIntoConstraints = NO;

    [NSLayoutConstraint activateConstraints:@[

        // constrain overlay1 to startPicker
        //  centerY
        //  leading / trailing = 0
        //  height = 38
        [_overlay1.centerYAnchor constraintEqualToAnchor:_startPicker.centerYAnchor],
        [_overlay1.leadingAnchor constraintEqualToAnchor:_startPicker.leadingAnchor constant:0.0],
        [_overlay1.trailingAnchor constraintEqualToAnchor:_startPicker.trailingAnchor constant:0.0],
        [_overlay1.heightAnchor constraintEqualToConstant:38.0],

        // constrain overlay2 to startPicker
        //  centerY
        //  leading / trailing = 0
        //  height = 38
        [_overlay2.centerYAnchor constraintEqualToAnchor:_endPicker.centerYAnchor],
        [_overlay2.leadingAnchor constraintEqualToAnchor:_endPicker.leadingAnchor constant:0.0],
        [_overlay2.trailingAnchor constraintEqualToAnchor:_endPicker.trailingAnchor constant:0.0],
        [_overlay2.heightAnchor constraintEqualToConstant:38.0],

        ]

     ];

}

And, this only needs to be called from viewDidLoad (or wherever else you may find it appropriate). There is no need for it to be -- and in fact, it should not be -- called from viewDidLayoutSubviews or viewWillTransitionToSize.

As a side note -- if you are using remove and re-add to show and hide them, you'll also get a little better optimization if you add them once, and then set the .hidden property to YES or NO.