我正在使用平移、捏合和旋转 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 布局”模式后,我不能总是用各种手势抓取视图(好像显示的视图不是手势识别器所理解的视图?)
我还有一个重置按钮,可将 UIView 设置transform
为身份,并将其center
设置为从 NIB 加载时的任何内容。但是在加载改变后的 UIView 中心和变换后,即使重置也不起作用。UIView 的位置不对。
我的第一个想法是,由于这些手势代码示例center
发生了变化,因此旋转必须围绕不同的中心进行(假设一些不可预测的移动、旋转和缩放序列)。由于我不想保存整个编辑序列(尽管如果我想在布局模式下拥有一些撤消功能,这可能会很方便),我更改了 UIPanGestureRecognizer 处理程序以使用转换来移动它。一旦我开始工作,我想只要保存转换就会让我得到当前的位置和方向,不管事情发生的顺序是什么。但没有这样的运气。我仍然以这种方式获得一个古怪的位置。
所以我很茫然。如果 UIView 已被移动并旋转到新位置,我该如何保存该位置和方向,以便稍后加载它并将 UIView 恢复到应有的位置?
如果我没有正确标记此内容或没有正确布局或犯了其他一些 stackoverflow 罪行,请提前道歉。这是我第一次在这里发帖。
编辑
到目前为止,我正在尝试这两个建议。我认为它们实际上是同一件事(一个建议保存框架,另一个建议保存原点,我认为是 frame.origin)。
所以现在首选项代码中的保存/加载包括以下内容。
节省:
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);
}
我得到了相同(或相似——很难说)的结果。事实上,我添加了一个按钮来重新加载首选项,一旦视图旋转,“重新加载”按钮将重复移动 UIView 一些偏移量(好像框架或变换是相对于自身的 - 我敢肯定是一个线索,但我不确定它指的是什么)。
编辑#2
这让我想知道取决于视图的frame
. 来自 Apple http://developer.apple.com/library/ios/#documentation/WindowsViews/Conceptual/ViewPG_iPhoneOS/WindowsandViews/WindowsandViews.html#//apple_ref/doc/uid/TP40009503-CH2-SW6(强调我的):
center 属性中的值始终有效,即使缩放或旋转因子已添加到视图的变换中。frame 属性中的值也不是这样,如果视图的变换不等于恒等变换,则认为该值无效。
编辑#3
好的,所以当我加载首选项时,一切看起来都很好。UI 面板的bounds
矩形是 {{0, 0}, {506, 254}}。在我的 VC 的 viewDidLoad 方法结束时,一切似乎都还可以。但是当事情真正被展示出来时,bounds
就是另外一回事了。例如:{{0, 0}, {488.321, 435.981}}(看起来就像旋转和缩放后它在其父视图中的大小)。如果我将界限重新设置为应有的界限,它就会移回原位。
将界限重置为他们应该以编程方式设置的界限很容易,但我实际上不确定何时执行!我本来想在 viewDidLoad 结束时这样做,但bounds
那时仍然是正确的。
编辑#4
我尝试在 initWithCoder 中捕获 self.bounds(因为它来自 NIB),然后在 layoutSubviews 中,将 self.bounds 重置为捕获的 CGRect。那行得通。
但它看起来非常骇人听闻并且充满了危险。这真的不是正确的方法。(可以吗?) skram 下面的回答似乎很简单,但在应用程序重新加载时对我不起作用。