Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jsp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 使用NSDictionary中的转换值还原CGRect_Objective C_Nsdictionary_Cgaffinetransform_Cgrect_Cgpoint - Fatal编程技术网

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;
}