使用NSDictionary中的Transform值恢复CGRect

问题描述 投票:1回答:1

我需要能够在UIImageView转换后保存框架。在下面的示例中,原始帧是将图像添加到超级视图的时间。然后,用户能够在灰色区域(superview)中的任何位置旋转,缩放和平移图像。

我拍摄这些图像并将其坐标保存到NSDictionary(这不是问题)。问题是,如果我在旋转后得到框架,则框架完全关闭。我需要能够在字典中存储带有变换的新帧,这样当用户返回到该视图并加载图像时,帧和保存的变换就像他们想要的那样。

摇摄

CGPoint translation = [gestureRecognizer translationInView:[object superview]];
if (CGRectContainsPoint(self.frame, CGPointMake([object center].x + translation.x,  [object center].y + translation.y))) {
    [object setCenter:CGPointMake([object center].x + translation.x, [object center].y + translation.y)];
    [gestureRecognizer setTranslation:CGPointZero inView:[object superview]];
}

旋转

self.transformRotation = CGAffineTransformRotate([[gestureRecognizer view] transform], [gestureRecognizer rotation]);

[gestureRecognizer view].transform = self.transformRotation;
if ( [gestureRecognizer rotation] != 0 ) {
    self.rotate = [gestureRecognizer rotation];
}
[gestureRecognizer setRotation:0];

缩放

self.transformScale = CGAffineTransformScale([[gestureRecognizer view] transform], [gestureRecognizer scale], [gestureRecognizer scale]);
[gestureRecognizer view].transform = self.transformScale;
if ( [gestureRecognizer scale] != 1 ) {
    self.scale = [gestureRecognizer scale];
}
[gestureRecognizer setScale:1];

使用视图的中心点可以使图像在第一次加载时保存时更接近原始位置。每次保存之后位置都相同,因为转换在该会话期间没有改变。

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

enter image description here

更新:稍微偏离并略大于原件

enter image description here

objective-c nsdictionary cgaffinetransform cgrect cgpoint
1个回答
3
投票

根据Apple document for UIView's transform property

当此属性的值不是identity变换时,frame属性中的值是未定义的,应该被忽略。

这就是为什么在改变frame后你无法获得transform的原因。

据我所知,在旋转,缩放或平移后,您希望保存当前状态以便以后恢复。在我看来,你需要做的就是每次更换时都保存transformcenter。在这种情况下,您不需要UIImageView

例如,frame是你的_transformTarget,保存它可以在下面的方法使用的当前状态(而不是保存在UIImageView,我使用NSDictionary。你可以将它改为NSUserDefaults

NSDictionary

在每个处理手势方法结束时,使用- (void)saveCurrentState { [[NSUserDefaults standardUserDefaults] setObject:NSStringFromCGAffineTransform(_transformTarget.transform) forKey:@"_transformTarget.transform"]; [[NSUserDefaults standardUserDefaults] setObject:NSStringFromCGPoint(_transformTarget.center) forKey:@"_transformTarget.center"]; } 保存当前状态。

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 } 的信息。在下次用户回来时,从您的字典中获取有关UIImageViewcenter的信息并再次设置它们。

transform

Result

有关更多详细信息,您可以查看我的样本repo - (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; }

© www.soinside.com 2019 - 2024. All rights reserved.