当用户退出“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的transform和center,如下所示:
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处理程序以使用变换来移动它。一旦我弄清楚了这一点,我认为只保存变换就可以获得当前的位置和方向,无论事情发生的顺序如何。但这样做没有成功。我仍然以奇怪的方式得到一个位置。
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一些偏移量(就像frame或transform相对于自身一样 - 我确定这是一个线索,但我不确定它指向什么)。
编辑#2
这让我想到依赖于视图的frame。来自苹果http://developer.apple.com/library/ios/#documentation/WindowsViews/Conceptual/ViewPG_iPhoneOS/WindowsandViews/WindowsandViews.html#//apple_ref/doc/uid/TP40009503-CH2-SW6(我强调):
价值中心属性始终有效,即使已将缩放或旋转因子添加到视图的变换中。如果视图的变换不等于标识变换,则frame属性中的值被认为是无效的。
编辑 #3
好的,当我加载偏好设置时,一切看起来都很正常。UI面板的bounds
矩形是{{0, 0},{506,254}}。在我的VC的viewDidLoad方法结束时,所有东西仍然看起来都很好。但是到实际显示事物的时候,bounds
变成了其他的东西。例如:{{0, 0},{488.321,435.981}}(旋转和缩放后在其父视图中的大小)。如果我将边界重置为它应该有的大小,它就会移回原位。
程序上将边界重置为应有的大小很容易,但我实际上不确定何时去这样做!我本来以为要在viewDidLoad的末尾这样做,但此时bounds
仍然正确。
编辑 #4
我尝试在initWithCoder(因为它来自NIB)中捕获self.bounds,然后在layoutSubviews中将self.bounds重置为捕获的CGRect。而那行得通。
但是这似乎非常笨拙并充满危险。这不可能是正确的方法。 (难道可以吗?) skram在下面的答案看起来很直接,但当应用程序重新加载时对我无效。