IOS control panel after turning the device

I am having problems with a few buttons after the rotation. When in portrait mode, the buttons are located at the bottom of the screen. When in landscape they move and change to be side by side at the bottom of the screen. All this works great, and the buttons behave correctly. However, if the phone then turns back to the portrait, the wrong button press area is only the left 1/3 of the buttons are available.

Here is the code that performs the rotation. (I also call this in viewWillAppear, so it always starts when the view is displayed, in case the view is already in the landscape.) I put the buttons in my own internal view.

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
                            duration:(NSTimeInterval)duration {


// determine our dimensions based on orientation
CGRect mainRect = [[UIScreen mainScreen] bounds];
CGFloat maxWidthHeight = MAX(mainRect.size.width, mainRect.size.height);
CGFloat minWidthHeight = MIN(mainRect.size.width, mainRect.size.height);
CGFloat _windowWidth = (UIDeviceOrientationIsPortrait(toInterfaceOrientation)) ? minWidthHeight : maxWidthHeight;


// get the current sizes of the things we are moving
CGRect saveRect = self.viewButtons.frame;
CGRect addLocRect = self.buttonAddLocation.frame;
CGRect connectRect = self.buttonConnect.frame;    

// This will be set below in one of the if-else branches
CGFloat buttonWidth = 0;

// determine the offset from the left/right based on device and orientation
int offset = 0;
if ([self isIphone]) {
    offset = (UIDeviceOrientationIsPortrait(toInterfaceOrientation)) ? OFFSET_LEFT_PORTRAIT_IPHONE : OFFSET_LEFT_LANDSCAPE_IPHONE;
} else {
    offset = (UIDeviceOrientationIsPortrait(toInterfaceOrientation)) ? OFFSET_LEFT_PORTRAIT_IPAD : OFFSET_LEFT_LANDSCAPE_IPAD;
}

// change the size & location of the button frame to just the button height to maximize the area for the location list
// no matter what orientation, the button frame will fill the bottom of the screen
saveRect.size.width = _windowWidth - 2*offset;
saveRect.origin.x = offset;

// for Landscape, move the buttons to side-by-side at the bottom of the window
if (UIInterfaceOrientationIsLandscape(toInterfaceOrientation)) {

    // size & move the buttons to fit side-by-side
    buttonWidth = (saveRect.size.width)*.4;

    addLocRect.origin.x += offset;
    addLocRect.origin.y = saveRect.size.height - addLocRect.size.height ;

    connectRect.origin.x = saveRect.size.width - buttonWidth - offset;
    connectRect.origin.y = saveRect.size.height - connectRect.size.height;

} else { // Portrait

    // move the buttons down to the bottom of the frame, stacked
    // size the buttons to be fully across the screen
    buttonWidth = saveRect.size.width;

    addLocRect.origin.y = 0 ; // at the top of the button view
    addLocRect.origin.x = 0;
    connectRect.origin.y = saveRect.size.height - connectRect.size.height;
    connectRect.origin.x = 0;

}

connectRect.size.width = buttonWidth;
addLocRect.size.width = buttonWidth;
self.buttonAddLocation.frame = addLocRect;
self.buttonConnect.frame = connectRect;
self.viewButtons.frame = saveRect;
}

I added several protocols to determine what happens to frames and borders at the end of a rotation:

 NSLog(@"Post rotation:");
 NSLog(@"AddLocation bounds: w=%f, h=%f, x=%f, y=%f", self.buttonAddLocation.frame.size.width, self.buttonAddLocation.frame.size.height,
      self.buttonAddLocation.frame.origin.x, self.buttonAddLocation.frame.origin.y);
 NSLog(@"AddLocation frame: w=%f, h=%f, x=%f, y=%f", self.buttonAddLocation.bounds.size.width, self.buttonAddLocation.bounds.size.height,
      self.buttonAddLocation.bounds.origin.x, self.buttonAddLocation.bounds.origin.y);

 NSLog(@"viewButtons bounds: w=%f, h=%f, x=%f, y=%f", self.viewButtons.frame.size.width, self.viewButtons.frame.size.height,
      self.viewButtons.frame.origin.x, self.viewButtons.frame.origin.y);
 NSLog(@"viewButtons frame: w=%f, h=%f, x=%f, y=%f", self.viewButtons.bounds.size.width, self.viewButtons.bounds.size.height,
      self.viewButtons.bounds.origin.x, self.viewButtons.bounds.origin.y);

:

Post rotation: (NOTE: Portrait, initial appearance)
AddLocation bounds: w=272.000000, h=55.000000, x=0.000000, y=0.000000
AddLocation frame: w=272.000000, h=55.000000, x=0.000000, y=0.000000
viewButtons bounds: w=272.000000, h=120.000000, x=24.000000, y=374.000000
viewButtons frame: w=272.000000, h=120.000000, x=0.000000, y=374.000000
Post rotation: (NOTE: rotate to Landscape)
AddLocation bounds: w=217.600006, h=55.000000, x=12.000000, y=65.000000
AddLocation frame: w=217.600006, h=55.000000, x=0.000000, y=0.000000
viewButtons bounds: w=544.000000, h=120.000000,  x=12.000000, y=374.000000
viewButtons frame: w=544.000000, h=120.000000, x=0.000000, y=374.000000
Post rotation: (NOTE: back to Portrait)
AddLocation bounds: w=272.000000, h=55.000000, x=0.000000, y=0.000000
AddLocation frame: w=272.000000, h=55.000000, x=0.000000, y=0.000000
viewButtons bounds: w=272.000000, h=120.000000, x=24.000000, y=138.000000
viewButtons frame: w=272.000000, h=120.000000, x=0.000000, y=374.000000

, , - viewButtons bounds origin.y, , - . .

?

: , struts spring IB , , . , , IB , . , .

+1
2

"tappable" . , , , :

  • , . , , .

  • , "" Subviews " xib ToBounds . , .

, .

+4

, , , , , UIView, , UIView . , UIView .

… viewButtons.origin.y , . .

UIView *rootView = [[[UIApplication sharedApplication] keyWindow] 
                                   rootViewController].view;
CGRect originalFrame = [[UIScreen mainScreen] bounds];
CGRect adjustedFrame = [rootView convertRect:originalFrame fromView:nil];
+2

All Articles