使用旋转手势的NSUndoManager撤销UIImage的旋转

5
如何使用NSUndoManager和旋转手势来旋转UIImageView?以下是我的旋转代码。
- (void)handleRotate:(UIRotationGestureRecognizer *)recognizer 
{
    if (recognizer.state == UIGestureRecognizerStateBegan) {
        prevRotation = 0.0;
    } 

    float thisRotate = recognizer.rotation - prevRotation;
    prevRotation = recognizer.rotation;
    recognizer.view.transform = CGAffineTransformRotate(recognizer.view.transform, thisRotate);

    CGPoint lastpoint = point;
}
1个回答

5

首先,阅读 “iPhone上使用撤消功能”。 确保在响应者链中某处设置了undoManager属性(可能是您的视图控制器)。

我们只希望在手势结束时推送撤消操作。 但是当我们推送撤消操作时,需要知道手势开始时视图的变换。 创建一个实例变量来保存原始变换:

@implementation YourViewController {
    CGAffineTransform _originalImageViewTransform;
}

接下来,我们需要一个方法来推送撤销操作并设置视图的变换:
- (void)setTransform:(CGAffineTransform)newTransform ofView:(UIView *)view
    undoTransform:(CGAffineTransform)undoTransform
{
    // If I'm called because the gesture ended, this pushes an undo action.
    // If I'm called because the user requested an undo, this pushes a redo action.
    [[self.undoManager prepareWithInvocationTarget:self]
        setTransform:undoTransform ofView:view undoTransform:newTransform];

    // Now actually set the transform.
    view.transform = newTransform;
}

您的handleRotate:方法需要检测手势的状态并采取适当的操作。

- (void)handleRotate:(UIRotationGestureRecognizer *)recognizer {
    UIView *view = recognizer.view;
    UIGestureRecognizerState state = recognizer.state;

    if (state == UIGestureRecognizerStateCancelled) {
        view.transform = _originalImageViewTransform;
        return;
    }

    if (state == UIGestureRecognizerStateBegan) {
        _originalImageViewTransform = view.transform;
    }

    CGAffineTransform transform = view.transform;
    transform = CGAffineTransformRotate(transform, recognizer.rotation);
    recognizer.rotation = 0; // This line means we don't need prevRotation

    if (state == UIGestureRecognizerStateEnded) {
        [[ The gesture ended, so push an undo action before setting the transform.
        [self setTransform:transform ofView:view undoTransform:_originalImageViewTransform];
    } else {
        // The gesture changed but didn't end, so don't push an undo action.
        view.transform = transform;
    }
}

但是,如果用户旋转了100次,则撤消重做功能将无法正常工作。用户必须按下100次撤消才能将其旋转到原始位置。因此,我希望仅为uigesturerecogniserstateended设置撤消管理器。如何做到这一点? - Prerna chavan
我很喜欢它,尽管我有许多需要撤消的属性。对于"创建一个实例变量来保存原始转换"_, 我可以在旋转手势中看到这一点,但如果你实现了平移、旋转、捏合、边框颜色、阴影、属性A、...属性Z。似乎为每个iVars设置在更改开始时可能会失控? - scooter133

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接