我在我的iOS應用程序中有UIToolbar
,我使用CGAffineTransform
以編程方式在willRotateToInterfaceOrientation
函數中旋轉。轉換需要縮放,旋轉和平移。我知道如何計算比例和旋轉參數,但似乎無法弄清楚如何計算翻譯參數,以便視圖位於正確的位置。經過大量的試驗和錯誤之後,我確定了將視圖移動到iPad上的正確位置的確切數字,但我不希望對數字進行硬編碼,以便代碼不會太依賴於設備。我如何計算翻譯參數?如何在iOS中旋轉視圖時計算仿射轉換參數?
這是我目前在包含工具欄的視圖控制器中的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];
最後,我使用的Xcode 4.5.1啓用ARC和我在iPad上(視網膜和非視網膜)5.1和6.0模擬器都測試。
感謝您的回覆。我的理解是,通過將給定的參數應用於現有的仿射變換,非Make函數(CGAffineTransformTranslate而不是CGAffineTransformMakeTranslate)構造一個新的變換矩陣。 – user19480 2013-03-25 01:28:04
@ user19480你完全正確,我的錯誤,我錯過了它不是Make類型的事實。道歉。 – WDUK 2013-03-25 01:40:15