UIToolbar
iOSアプリに、を使用して関数内でプログラムで回転するがありwillRotateToInterfaceOrientation
ますCGAffineTransform
。変換には、スケーリング、回転、および平行移動が必要です。スケールと回転のパラメーターを計算する方法は知っていますが、ビューが正しい位置に表示されるように平行移動パラメーターを計算する方法を理解できないようです。試行錯誤の末、iPadの適切な場所にビューを移動するための正確な数値を決定しましたが、コードがデバイスに依存しすぎないように、数値をハードコーディングしないことをお勧めします。変換パラメータを計算するにはどうすればよいですか?
これが、ツールバーを含むViewControllerの現在のwillRotateToInterfaceOrientation
関数です。値をハードコーディングするのではなくtx
、以下の計算方法を知りたいです。ty
ツールバーとウィンドウサイズのさまざまな機能を使用してみましたが、ツールバーは常にウィンドウの下部ではなく、ウィンドウの奇妙な場所またはウィンドウの外側に重なって表示されます。
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
if (UIInterfaceOrientationIsLandscape(toInterfaceOrientation))
{
// First, apply identify transformation to simplify later calculations and also because we need the toolbar's frame and Apple's docs say you cannot use a view's frame if the transform property is not the identity matrix.
self.toolbar.transform = CGAffineTransformIdentity;
// Calculate affine parameters.
// Expand width to the window's height when in landscape mode, leaving the toolbar's height unchanged.
UIWindow *window = [[UIApplication sharedApplication] keyWindow];
CGFloat sx = 1.0;
CGFloat sy = window.frame.size.height / window.frame.size.width;
// Rotate 90 degrees in either direction depending on the orientation direction change.
CGFloat rotate = M_PI_2;
if (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft)
{
rotate = -M_PI_2;
}
// Reposition the toolbar.
// TODO: Calculate values rather than hard-coding them. Why is tx not something like ((window.frame.size.width / 2) - (self.toolbar.frame.size.height / 2))?
// Note that these values work for both the original iPad and iPad Retina, presumably because the values represent points not pixels.
CGFloat tx = -365.5;
CGFloat ty = 359.5;
if (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft)
{
tx = -tx;
}
// Apply affine transformation.
CGAffineTransform transform = CGAffineTransformMakeScale(sx, sy);
transform = CGAffineTransformRotate(transform, rotate);
transform = CGAffineTransformTranslate(transform, tx, ty);
[UIView animateWithDuration:duration
animations:^{
self.toolbar.transform = transform;
}
completion:NULL
];
}
else if (toInterfaceOrientation == UIInterfaceOrientationPortrait)
{
[UIView animateWithDuration:duration
animations:^{
self.toolbar.transform = CGAffineTransformIdentity;
}completion:NULL
];
}
else if (toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)
{
NSLog(@"Upside-down orientation not supported");
}
}
さらに、これが私のツールバーの宣言と基本的な初期化です。ツールバーをサブビューとしてメインウィンドウに追加し、手動で回転を処理していることに注意してください。これは、アプリにUITabBarController
ルートビューコントローラーがあり、これがツールバーをタブバーの上に表示する唯一の方法だったためです。
// The toolbar is strong since this controller must maintain ownership as the toolbar is removed from the parent view when this view disappears.
@property (strong, nonatomic) IBOutlet UIToolbar *toolbar;
UIWindow *window = [[UIApplication sharedApplication] keyWindow];
CGFloat height = CGRectGetHeight(self.tabBarController.tabBar.frame); // Completely cover the tab bar.
CGFloat x = window.frame.origin.x;
CGFloat y = window.frame.size.height - height;
CGFloat width = window.frame.size.width;
self.toolbar.frame = CGRectMake(x, y, width, height);
[window addSubview:self.toolbar];
最後に、ARCを有効にしてXcode 4.5.1を使用し、iPad(Retinaおよび非Retina)5.1および6.0シミュレーターの両方でテストしています。