Objective c 使用NSDictionary中的转换值还原CGRect
转换Objective c 使用NSDictionary中的转换值还原CGRect,objective-c,nsdictionary,cgaffinetransform,cgrect,cgpoint,Objective C,Nsdictionary,Cgaffinetransform,Cgrect,Cgpoint,转换UIImageView后,我需要能够保存帧。在下面的示例中,原始帧在图像添加到superview时显示。然后,用户可以在灰色区域(superview)的任何位置旋转、缩放和平移图像 我拍摄这些图像并将其坐标保存到NSDictionary(这不是问题)。问题是,如果我在旋转后得到帧,帧将完全关闭。我需要能够在字典中存储带有transform的新帧,以便当用户返回此视图并加载图像时,帧和保存的转换与预期的一样 淘金 旋转的 缩放比例 使用视图的中心点可使图像在第一次加载时保存时更接近原始位置。每
UIImageView
后,我需要能够保存帧。在下面的示例中,原始帧在图像添加到superview时显示。然后,用户可以在灰色区域(superview)的任何位置旋转、缩放和平移图像
我拍摄这些图像并将其坐标保存到NSDictionary(这不是问题)。问题是,如果我在旋转后得到帧,帧将完全关闭。我需要能够在字典中存储带有transform的新帧,以便当用户返回此视图并加载图像时,帧和保存的转换与预期的一样
淘金
旋转的
缩放比例
使用视图的中心点可使图像在第一次加载时保存时更接近原始位置。每次保存后,位置都是相同的,因为转换在该会话期间没有更改
- (CGPoint)centerOnCanvas {
CGPoint originalCenter = self.center;
return originalCenter;
}
- (CGRect)frameOnCanvas {
return CGRectMake(
self.preTransformedFrame.origin.x,
self.preTransformedFrame.origin.y,
self.preTransformedFrame.size.width,
self.preTransformedFrame.size.height
);
}
- (CGRect)preTransformedFrame {
CGAffineTransform currentTransform = self.transform;
self.transform = CGAffineTransformIdentity;
CGRect originalFrame = self.bounds;
self.transform = currentTransform;
return originalFrame;
}
更新:稍微偏下,比原来的稍微大一点
根据
如果此属性的值不是标识转换,则框架属性中的值未定义,应忽略
这就是为什么在更改变换
后无法获得帧
据我所知,在旋转、缩放或平移之后,您希望保存当前状态以供以后恢复。在我看来,每次更改时,只需保存ui图像视图的transform
和center
。在这种情况下,您不需要使用frame
例如,\u transformTarget
是您的UIImageView
,要保存其当前状态,您可以使用下面的方法(不是保存在NSDictionary
中,而是使用NSUserDefaults
。您可以将其更改为NSDictionary
)
在每个处理手势方法结束时,使用saveCurrentState
保存当前状态
- (void)handlePanGesture:(UIPanGestureRecognizer*)gesture {
CGPoint translation = [gesture translationInView:self.view];
CGPoint newCenter = CGPointMake(_transformTarget.center.x + translation.x, _transformTarget.center.y + translation.y);
if (CGRectContainsPoint(self.view.frame, newCenter)) {
_transformTarget.center = newCenter;
[gesture setTranslation:CGPointZero inView:self.view];
[self saveCurrentState]; // Save current state when center is changed
}
}
- (void)handleRotationGesture:(UIRotationGestureRecognizer*)gesture {
_transformTarget.transform = CGAffineTransformRotate(_transformTarget.transform, gesture.rotation);
gesture.rotation = 0;
[self saveCurrentState]; // Save current state when transform is changed
}
- (void)handlePinchGesture:(UIPinchGestureRecognizer*)gesture {
_transformTarget.transform = CGAffineTransformScale(_transformTarget.transform, gesture.scale, gesture.scale);
gesture.scale = 1;
[self saveCurrentState]; // Save current state when transform is changed
}
现在,每次更改UIImageView
时都会保存有关它的信息。下次用户回来时,从字典中获取有关center
和transform
的信息并重新设置
- (void)restoreFromSavedState {
NSString *transformString = [[NSUserDefaults standardUserDefaults] objectForKey:@"_transformTarget.transform"];
CGAffineTransform transform = transformString ? CGAffineTransformFromString(transformString) : CGAffineTransformIdentity;
NSString *centerString = [[NSUserDefaults standardUserDefaults] objectForKey:@"_transformTarget.center"];
CGPoint center = centerString ? CGPointFromString(centerString) : self.view.center;
_transformTarget.center = center;
_transformTarget.transform = transform;
}
后果
有关更多详细信息,请查看我的回购示例
最好将宽度
、高度
和旋转
值保存到用户默认值中。能否显示旋转、缩放和平移图像的代码?如果您使用CGAffineTransform
制作它们,我认为您不需要保存帧。@trungduc已更新。这个示例现在很有意义,因为我尝试了旋转和缩放。。。因此,仅应用最后的转换和保存看起来对您有效。我试图简化我的代码,但我仍然有一些坐标关闭的问题。想知道这是否是因为手势代码在my object(在您的例子中是UIImageView)类中,而不是superview本身。我以superview框架为基础,所以我不明白为什么这会成为一个问题。@Wrightsc我不知道你在说什么。你能解释一下“坐标偏离”吗?我认为object类中的句柄手势不会导致任何问题。如果你想让我处理对象类中的所有事情,我会尝试让它看到原始问题中更新的图像,稍微大一点的图像和帧有点不合适,但是我在保存和检索时检查了变换和中心字符串,它们是相同的,所以不确定为什么会有不同!当然可以。在我看来,在这种情况下你不应该使用自动布局。我认为自动布局是你的原因problem@WrightsCS我认为您仍然可以为画布视图添加约束。但是,在为内部对象应用中心和变换之前,请尝试调用layoutifneed
,以确保画布的框架在应用中心和变换后不会发生更改(这可能会导致问题)
- (CGPoint)centerOnCanvas {
CGPoint originalCenter = self.center;
return originalCenter;
}
- (CGRect)frameOnCanvas {
return CGRectMake(
self.preTransformedFrame.origin.x,
self.preTransformedFrame.origin.y,
self.preTransformedFrame.size.width,
self.preTransformedFrame.size.height
);
}
- (CGRect)preTransformedFrame {
CGAffineTransform currentTransform = self.transform;
self.transform = CGAffineTransformIdentity;
CGRect originalFrame = self.bounds;
self.transform = currentTransform;
return originalFrame;
}
- (void)saveCurrentState {
[[NSUserDefaults standardUserDefaults] setObject:NSStringFromCGAffineTransform(_transformTarget.transform) forKey:@"_transformTarget.transform"];
[[NSUserDefaults standardUserDefaults] setObject:NSStringFromCGPoint(_transformTarget.center) forKey:@"_transformTarget.center"];
}
- (void)handlePanGesture:(UIPanGestureRecognizer*)gesture {
CGPoint translation = [gesture translationInView:self.view];
CGPoint newCenter = CGPointMake(_transformTarget.center.x + translation.x, _transformTarget.center.y + translation.y);
if (CGRectContainsPoint(self.view.frame, newCenter)) {
_transformTarget.center = newCenter;
[gesture setTranslation:CGPointZero inView:self.view];
[self saveCurrentState]; // Save current state when center is changed
}
}
- (void)handleRotationGesture:(UIRotationGestureRecognizer*)gesture {
_transformTarget.transform = CGAffineTransformRotate(_transformTarget.transform, gesture.rotation);
gesture.rotation = 0;
[self saveCurrentState]; // Save current state when transform is changed
}
- (void)handlePinchGesture:(UIPinchGestureRecognizer*)gesture {
_transformTarget.transform = CGAffineTransformScale(_transformTarget.transform, gesture.scale, gesture.scale);
gesture.scale = 1;
[self saveCurrentState]; // Save current state when transform is changed
}
- (void)restoreFromSavedState {
NSString *transformString = [[NSUserDefaults standardUserDefaults] objectForKey:@"_transformTarget.transform"];
CGAffineTransform transform = transformString ? CGAffineTransformFromString(transformString) : CGAffineTransformIdentity;
NSString *centerString = [[NSUserDefaults standardUserDefaults] objectForKey:@"_transformTarget.center"];
CGPoint center = centerString ? CGPointFromString(centerString) : self.view.center;
_transformTarget.center = center;
_transformTarget.transform = transform;
}