Search code examples
ioscgrect

iOS, Graceful Orientation Change


I call this function at viewDidLoad and didRotateFromInterfaceOrientation

-(void) makeBox{
    [self.view1 removeFromSuperview];

    float viewWidth = CGRectGetWidth(self.view.frame);
    float viewHeight = CGRectGetHeight(self.view.frame);
    float startx = (viewWidth / 100) * 10;
    float starty = (viewHeight /100) * 20;

    float width = (viewWidth / 100) * 80;
    float height = (viewHeight /100) * 60;

    CGRect frame1 = CGRectMake(startx, starty, width, height);
    self.view1 = [[UIView alloc] initWithFrame:frame1];
    [self.view1 setBackgroundColor:[UIColor redColor]];

    [self.view addSubview:self.view1];  
}

When the view does change, its very 'sketchy' & not very graceful at all. I'm using simulator but i assume that it would be the same if i were to run on a device. How would i go about making this transition smoother? I would post to user experiance page, but i wish todo this programmatically

The overall point of this, other than to learn, is to achieve orientation independent graphics from code (without autolayout).


Solution

  • There's no need to remove the view and create a new one with the desired frame if its the only thing you're changing. Just modify the view frame in-place:

    - (void)makeBox {
        CGFloat viewWidth = CGRectGetWidth(self.view.frame);
        CGFloat viewHeight = CGRectGetHeight(self.view.frame);
        CGFloat startx = (viewWidth / 100) * 10;
        CGFloat starty = (viewHeight /100) * 20;
    
        CGFloat width = (viewWidth / 100) * 80;
        CGFloat height = (viewHeight /100) * 60;
    
        CGRect view1Frame = CGRectMake(startx, starty, width, height);
    
        if (!self.view1) {
            // The view doesn't exists yet, we create it
            self.view1 = [[UIView alloc] initWithFrame:view1Frame];
            [self.view1 setBackgroundColor:[UIColor redColor]];
            [self.view addSubview:self.view1];
        }
        else {
            // Just update the frame
            self.view1.frame = view1Frame;
        }
    }
    

    For extra-nice UX, wrap the frame update in an animation block:

    // ... snip ...
    else {
        [UIView animateWithDuration:0.3 animations:^() {
            self.view1.frame = view1Frame;
        }];
    }