1

私は CgLayer で unod redo 操作を行っています。いくつかのコードを試しましたが、動作させることができませんでした。どこが間違っているのかわかりません。以下は私のコードです。

これは私の drawRect 関数です

- (void)drawRect:(CGRect)rect
{    
    m_backgroundImage = [UIImage imageNamed:@"bridge.jpg"];

    CGPoint drawingTargetPoint = CGPointMake(0,0);
    [m_backgroundImage drawAtPoint:drawingTargetPoint];


    switch(drawStep)
    {
          case DRAW:
          {
              CGContextRef context = UIGraphicsGetCurrentContext();

              if(myLayerRef == nil)
              {

                  myLayerRef = CGLayerCreateWithContext(context, self.bounds.size, NULL);
              }   

              CGContextDrawLayerAtPoint(context, CGPointZero, myLayerRef); 
              break;
          }           

         case UNDO:
         {            
              [curImage drawInRect:self.bounds];              
              break;
         }

        default:
            break;
    }      
}

タッチが終了したら、レイヤーを NSValue に変換し、keyValue ペアとして NSDictionary に格納してから、辞書オブジェクトを配列に追加します。

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{        
    NSValue *layerCopy = [NSValue valueWithPointer:myLayerRef];


    NSDictionary *lineInfo = [NSDictionary dictionaryWithObjectsAndKeys:layerCopy, @"IMAGE",
                              nil];

    [m_pathArray addObject:lineInfo];    
    NSLog(@"%i",[m_pathArray count]);

}

以下は私の元に戻す機能です

- (void)undoButtonClicked
{   
    if([m_pathArray count]>0)
    {
        NSMutableArray *_line=[m_pathArray lastObject];
        [m_bufferArray addObject:[_line copy]];
        [m_pathArray removeLastObject];
        drawStep = UNDO;
        [self redrawLine];
    } 
}

//Redraw functions

- (void)redrawLine
{
    NSDictionary *lineInfo = [m_pathArray lastObject];

    NSValue *val = [lineInfo valueForKey:@"IMAGE"];

    CGLayerRef  layerToShow = (CGLayerRef) [val pointerValue];

    CGContextRef context1 = CGLayerGetContext(layerToShow);
    CGContextDrawLayerAtPoint(context1, CGPointMake(00, 00),layerToShow);
    [self setNeedsDisplayInRect:self.bounds];
}

ここが間違っていると思います。だから友達は私を助けてください。

以下のコメントから、Cglayer に描画する関数を追加しました (この関数は touchesMovedEvent.

- (void) drawingOperations
{    
    CGContextRef context1 = CGLayerGetContext(myLayerRef);    

    CGPoint mid1 = midPoint(m_previousPoint1, m_previousPoint2); 
    CGPoint mid2 = midPoint(m_currentPoint, m_previousPoint1);     

    CGContextMoveToPoint(context1, mid1.x, mid1.y);
    CGContextAddQuadCurveToPoint(context1, m_previousPoint1.x, m_previousPoint1.y, mid2.x, mid2.y); 
    CGContextSetLineCap(context1, kCGLineCapRound);
    CGContextSetLineWidth(context1, self.lineWidth);
    CGContextSetStrokeColorWithColor(context1, self.lineColor.CGColor);           
    CGContextSetAllowsAntialiasing(context1, YES);
    CGContextSetInterpolationQuality(context1, kCGInterpolationHigh); 
    CGContextSetAlpha(context1, self.lineAlpha);
    CGContextStrokePath(context1);    
}

よろしくランジット

4

2 に答える 2

1

元に戻すとやり直しを実装する最良の方法は、NSUndoManager元に戻すまたはやり直すオブジェクトの各状態を保存する必要がない簡単な説明として実装することです NSUndoManager 自体がこれを作成します...

これに到達するための手順は次のとおりです。

1- NSUndoManager を初期化します。

2-指定された関数呼び出しを使用して NSUndoManager オブジェクトにオブジェクトの状態を登録する これについては、後で説明します。

3-NSUndoManagerオブジェクトで元に戻す、やり直し、またはクリアアクション機能を使用します。

私の作業ソリューションの例

-in .h ファイル

@property (nonatomic,retain) NSUndoManager *undoManager;
  • .m ファイルで

    @synthesize undoManager;

  • 「viewDidLoad」メソッドで -- NSUndoManager を初期化します

    undoManager = [[NSUndoManager alloc] init];

クラスに、ピンチを使用してズームイン/ズームアウトする関数があるとします。そのため、「viewDidLoad」には次のようになります。

UIPinchGestureRecognizer *pinchGesture =
    [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinch:)];
    pinchGesture.delegate = (id)self;
    [self.view addGestureRecognizer:pinchGesture];

「MyImageView」はズームイン/アウトしたい画像であることに注意してください

- (void)pinch:(UIPinchGestureRecognizer*)recognizer{

    if (recognizer.state == UIGestureRecognizerStateEnded || recognizer.state == UIGestureRecognizerStateChanged) {
        NSLog(@"gesture.scale = %f", recognizer.scale);

        CGFloat currentScale = self.MyImageView.frame.size.width / self.MyImageView.bounds.size.width;
        CGFloat newScale = currentScale * recognizer.scale;
        //Here is the line that register image to NSUndoManager before making and adjustments to the image "save current image before changing the transformation"
        //Add image function is function that fired when you Make undo action using NSUndoManager "and so we maintain only image transformation that changed when you zoom in/out"
         [[undoManager prepareWithInvocationTarget:self] AddImage:self.MyImageView.transform];

        if (newScale < 0.5) {
            newScale = 0.5;
        }
        if (newScale > 5) {
            newScale = 5;
        }

        CGAffineTransform transform = CGAffineTransformMakeScale(newScale, newScale);
        self.MyImageView.transform = transform;
        recognizer.scale = 1;
    }
}

-AddImage 関数は、現在の画像変換状態を NSUndoManager に保存します。

-(void)AddImage:(CGAffineTransform)sender{
    CGAffineTransform transform = sender;
    self.MyImageView.transform = transform;
}

したがって、元に戻すアクションを行うボタンがある場合

-(IBAction)OptionsBtn:(id)sender{
  if ([undoManager canUndo]) {
      [undoManager undo];
  }
}

したがって、すべてのアクションをキャンセルしたい場合は、両方の方法があります

while ([undoManager canUndo]) {
   [undoManager undo];
}

また

[undoManager removeAllActions];
于 2012-07-18T12:35:49.057 に答える
0
- (void)redrawLine
{
    NSDictionary *lineInfo = [m_pathArray lastObject];
    NSValue *val = [lineInfo valueForKey:@"IMAGE"];
    CGContextRef context1 = (CGContextRef) [val pointerValue];
    CGContextDrawLayerAtPoint(context1, CGPointMake(00, 00),layerToShow);
    [self setNeedsDisplayInRect:self.bounds];
}

このメソッドをコードで更新するだけです

于 2012-08-23T05:57:33.520 に答える