gpt4 book ai didi

ios - 在 iOS 中旋转 View 时如何计算仿射平移参数?

转载 作者:行者123 更新时间:2023-12-01 18:23:35 27 4
gpt4 key购买 nike

我有一个 UIToolbar在我以编程方式在 willRotateToInterfaceOrientation 中旋转的 iOS 应用程序中使用 CGAffineTransform 的函数.变换需要缩放、旋转和平移。我知道如何计算比例和旋转参数,但似乎无法弄清楚如何计算平移参数,以便 View 位于正确的位置。经过大量试验和错误后,我确定了将 View 移动到 iPad 上正确位置的确切数字,但我不希望对数字进行硬编码,以免代码过于依赖设备。如何计算翻译参数?

这是我目前的willRotateToInterfaceOrientation包含工具栏的 View Controller 中的函数。我想知道如何计算txty下面而不是硬编码这些值。我尝试过使用工具栏和窗口大小的各种功能,但工具栏总是出现在一个奇怪的位置或完全在窗口之外而不是在窗口底部与窗口重叠。

- (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");
}
}

此外,这里是我的工具栏的声明和基本初始化。请注意,我将工具栏作为 subview 添加到主窗口并手动处理旋转,因为我的应用程序有 UITabBarController作为 Root View Controller ,这是我可以让工具栏出现在选项卡栏顶部的唯一方法。
// 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 模拟器上进行测试。

最佳答案

使用 CGAffineTransform,您需要非常小心地执行操作,并且(正如 David 提到的)您需要知道您正在旋转或调整大小的位置。人们常常对旋转的结果感到惊讶,而不管 anchor (您使用仿射旋转的点)。

如果我们有这个作为我们的起始 View :

original view

您可以让 anchorPoint 位于 (0, 0) 或图像的中心。任何一个都可以工作。两者都不可能单独给您想要的东西。

这是从 0 到 0:

rotated by 90

如果您只是想旋转 View 以显示它,如果您有 0、0 anchor ,您会旋转并想知道“我的 View 发生了什么!!!”但是你可以把它翻译到你想要的地方。

这是在图像中心设置的 anchor :

rotated about center

您可以看到结果 View ,但它在垂直和水平方向上都关闭了,因为它是一个矩形并且边长不同。但是,您可以通过将 x 移动原始高度差并将 y 移动原始宽度差来轻松调整它。

关于ios - 在 iOS 中旋转 View 时如何计算仿射平移参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15606179/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com