iphone - 从设置加载 UIView 变换和中心会给出不同的位置

标签 iphone uiview transform uigesturerecognizer center

我正在使用平移、捏合和旋转 UIGestureRecognizers 来允许用户将某些 UI 元素准确放置在他们想要的位置。使用这里的代码 http://www.raywenderlich.com/6567/uigesturerecognizer-tutorial-in-ios-5-pinches-pans-and-more (或来自此处的类似代码 http://mobile.tutsplus.com/tutorials/iphone/uigesturerecognizer/ )都为我提供了用户根据需要放置这些 UI 元素所需的内容。

当用户退出“UI 布局”模式时,我像这样保存 UIView 的变换和居中:

NSString *transformString = NSStringFromCGAffineTransform(self.transform);
[[NSUserDefaults standardUserDefaults] setObject:transformString forKey:@"UItransform", suffix]];

NSString *centerString = NSStringFromCGPoint(self.center);
[[NSUserDefaults standardUserDefaults] setObject:centerString forKey:@"UIcenter"];

当我重新加载应用程序时,我会像这样读取 UIView 的变换和居中:
NSString *centerString = [[NSUserDefaults standardUserDefaults] objectForKey:@"UIcenter"];
if( centerString != nil )
    self.center = CGPointFromString(centerString);

NSString *transformString = [[NSUserDefaults standardUserDefaults] objectForKey:@"UItransform"];

if( transformString != nil )
    self.transform = CGAffineTransformFromString(transformString);

UIView 最终正确旋转和缩放,但位置错误。此外,再次进入“UI 布局”模式时,我不能总是用各种手势抓取 View (好像显示的 View 不是手势识别器理解的 View ?)

我还有一个重置按钮,用于设置 UIView 的 transform到身份及其center无论它从 NIB 加载时是什么。但是在加载改变后的 UIView 中心和转换后,即使重置也不起作用。 UIView 的位置是错误的。

我的第一个想法是,因为这些手势代码示例改变了 center ,旋转必须围绕不同的中心发生(假设一些不可预测的移动、旋转和缩放顺序)。由于我不想保存整个编辑序列(尽管如果我想在布局模式下具有一些撤消功能,这可能会很方便),我更改了 UIPanGestureRecognizer 处理程序以使用变换来移动它。一旦我开始工作,我想只要保存变换就可以获得当前的位置和方向,无论事情发生的顺序如何。但没有这样的运气。我仍然以这种方式得到一个古怪的位置。

所以我不知所措。如果 UIView 已被移动并旋转到新位置,我该如何保存该位置和方向,以便稍后加载它并使 UIView 返回到应有的位置?

如果我没有正确标记这个或没有正确布局或犯下其他一些stackoverflow罪,请提前道歉。这是我第一次在这里发帖。

编辑

到目前为止,我正在尝试这两个建议。我认为它们实际上是一回事(一个建议保存框架,另一个建议保存原点,我认为是 frame.origin)。

所以现在从 prefs 代码保存/加载包括以下内容。

节省:
NSString *originString = NSStringFromCGPoint(self.frame.origin);
[[NSUserDefaults standardUserDefaults] setObject:originString forKey:@"UIorigin"];

加载(加载转换之前):
NSString *originString = [[NSUserDefaults standardUserDefaults] objectForKey:@"UIorigin"];
if( originString ) {
    CGPoint origin = CGPointFromString(originString);
    self.frame = CGRectMake(origin.x, origin.y, self.frame.size.width, self.frame.size.height);
}

我得到相同(或类似 - 很难说)的结果。事实上,我添加了一个按钮来重新加载首选项,一旦 View 旋转,“重新加载”按钮将重复移动 UIView 一些偏移(好像框架或变换是相对于自身的 - 我确定是一个线索,但我不确定它指的是什么)。

编辑#2

这让我想知道取决于 View 的 frame .来自苹果 http://developer.apple.com/library/ios/#documentation/WindowsViews/Conceptual/ViewPG_iPhoneOS/WindowsandViews/WindowsandViews.html#//apple_ref/doc/uid/TP40009503-CH2-SW6 (强调我的):

The value in the center property is always valid, even if scaling or rotation factors have been added to the view’s transform. The same is not true for the value in the frame property, which is considered invalid if the view’s transform is not equal to the identity transform.



编辑 #3

好的,所以当我加载首选项时,一切看起来都很好。 UI面板的bounds矩形是 {{0, 0}, {506, 254}}。在我的 VC 的 viewDidLoad 方法结束时,一切似乎都还可以。但是到实际显示时,bounds是别的东西。例如:{{0, 0}, {488.321, 435.981}}(它看起来像旋转和缩放后它在其父 View 中的大小)。如果我将边界重置为它应该是的样子,它就会移回原位。

以编程方式将边界重置为他们应该设置的范围很容易,但我实际上不确定何时这样做!我本来想在 viewDidLoad 结束时这样做,但是 bounds在这一点上仍然是正确的。

编辑 #4

我尝试在 initWithCoder 中捕获 self.bounds(因为它来自 NIB),然后在 layoutSubviews 中,将 self.bounds 重置为捕获的 CGRect。这有效。

但这似乎非常骇人听闻,而且充满危险。这真的不是这样做的正确方法。 (可以吗?)下面 skram 的回答看起来很简单,但在应用程序重新加载时对我不起作用。

最佳答案

您将保存 frame属性(property)也是如此。您可以使用 NSStringFromCGRect()CGRectFromString() .

加载时,设置框架然后应用您的变​​换。这就是我在我的一个应用程序中的做法。

希望这可以帮助。

更新 :就我而言,我有 Draggable UIViews可以应用旋转和调整大小。我用 NSCoding保存和加载我的对象,示例如下。

//encoding
....
[coder encodeCGRect:self.frame forKey:@"rect"];
// you can save with NSStringFromCGRect(self.frame);
[coder encodeObject:NSStringFromCGAffineTransform(self.transform) forKey:@"savedTransform"];

//init-coder
CGRect frame = [coder decodeCGRectForKey:@"rect"];
// you can use frame = CGRectFromString(/*load string*/);
[self setFrame:frame];
self.transform = CGAffineTransformFromString([coder decodeObjectForKey:@"savedTransform"]);

这样做是保存我的框架和转换,并在需要时加载它们。相同的方法可以应用于 NSStringFromCGRect()CGRectFromString() .

更新 2 : 你的情况。你会做这样的事情..
[self setFrame:CGRectFromString([[NSUserDefaults standardUserDefaults] valueForKey:@"UIFrame"])];
self.transform = CGAffineTransformFromString([[NSUserDefaults standardUserDefaults] valueForKey:@"transform"]);

假设您要保存到 NSUserDefaultsUIFrame , 和 transform键。

关于iphone - 从设置加载 UIView 变换和中心会给出不同的位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11008462/

相关文章:

html - 变换在 HTML 和 CSS 中旋转表头

ios - 无法将 PrototypeCell 添加到 xib 文件中的 UITableView

ios - 了解 convertPoint :toView:

iPhone iOS 如何渲染具有不同分辨率或比例的屏幕截图?

css - 使用 css 变换移动时,SVG 图像变得模糊和闪烁

c# - XAML - 如何反转 UIElement.RenderTransform?

iphone - 您应该使用哪个数据库来编写 iPhone/iPad 应用程序?

iphone - 我在 Cocoa 的 SOAP XML 中使用什么数据类型作为整数?

iphone - 转换点 :toView: Doesn't seem to be working

ios - 从 UIViewController 过渡到另一个