回転後のいくつかのボタンに問題があります。縦向きモードの場合、ボタンは画面の下部に積み重ねられます。横向きの場合、それらは移動およびサイズ変更されて、画面の下部に並べられます。これはすべてうまく機能し、ボタンは正しく動作します。ただし、電話を縦向きに戻すと、ボタンのタップ領域が正しくなくなり、ボタンの左 1/3 のみがタップ可能になります。
回転を行うコードは次のとおりです。(viewWillAppear 内でも呼び出すので、ビューが既に横向きになっている場合に備えて、ビューが表示されたときに常に実行されます。) ボタンを独自の内部ビューに配置しました。
- (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;
}
回転の最後にフレームと境界で何が起こっているかを判断するために、いくつかのログを追加しました。
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 の境界 origin.y ですが、それを設定しようとすると、めちゃくちゃになってしまいます。ボタンが突然画面の上部に表示されます。ボタンの境界は十分に広いです。
私は何が欠けていますか?
更新: ビューのフレームを設定したコードと戦っていた、囲むビュー用に IB でストラットとスプリングを設定したという事実を見逃していました。フレームを設定するコードを削除し、IB に作業を任せ、ボタンのオフセットをいじりました。最も美しい解決策ではありませんが、解放する必要があります。