2

UIImageのサブクラスであるMNTRectangleというクラスがあります。このクラスの drawRect メソッドをオーバーライドして、(フレームを使用して) 画像に境界線を描画しました。ユーザーがDocumentView(UIViewのサブクラス)と呼ばれるクラスでパン/ドラッグジェスチャを開始すると、MNTRectangleのインスタンスがサブビューとしてDocumentViewのインスタンスに追加されます。ユーザーがドラッグを続けると、MNTRectangle のサイズが変更されます。問題は、MNTRectangle が最後に黒一色で表示されることです。境界線を描画する前にグラフィックス コンテキストをクリアし、コンテキストを保存し、境界線を描画した後にコンテキストを復元しようとしました。何をしようとしても、MNTRectangleをクリアして、サイズ変更時に境界線を表示することはできません。

MNTRectangle クラスのコードは次のとおりです。

@implementation MNTRectangle

- (id)init
{
    self = [super init];

    if (self)
    {
        [self setup];
    }

    return self;
}

- (id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder:aDecoder];

    if (self)
    {
        [self setup];
    }

    return self;
}

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];

    if (self)
    {
        [self setup];
    }

    return self;
}

- (void)setup
{
    [self setBackgroundColor:[UIColor clearColor]];
}

- (void)drawRect:(CGRect)rect
{
    // Get graphics context
    CGContextRef context = UIGraphicsGetCurrentContext();

//    CGContextSaveGState(context);

//    CGContextClearRect(context, rect);

    // Draw border
    CGContextSetLineWidth(context, 4.0);
    [[UIColor blackColor] setStroke];
    CGContextStrokeRect(context, rect);

//    CGContextRestoreGState(context);
}

UIView でのパン/ドラッグ処理のための DocumentView のコードは次のとおりです。

-(id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];

    if (self)
    {
         _panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
    }

    return self;
}

- (void)handlePan:(UIPanGestureRecognizer *)sender
{
    if ([sender state] == UIGestureRecognizerStateBegan)
    {
        _startPanPoint = [sender locationInView:self];

        MNTRectangle *rectangle = [[MNTRectangle alloc] initWithFrame:CGRectMake(_startPanPoint.x, _startPanPoint.y, 1, 1)];
        [_objects addObject:rectangle];
        _currentPanObject = rectangle;
        [self addSubview:rectangle];
    }
    else if ([sender state] == UIGestureRecognizerStateChanged)
    {
        CGPoint endPanPoint = [sender locationInView:self];

        float height = fabsf(endPanPoint.y - _startPanPoint.y);
        float width = fabsf(endPanPoint.x - _startPanPoint.x);
        float x = MIN(_startPanPoint.x, endPanPoint.x);
        float y = MIN(_startPanPoint.y, endPanPoint.y);

        MNTRectangle *rectangle = (MNTRectangle *)_currentPanObject;
        [rectangle setFrame:CGRectMake(x, y, width, height)];
    }
    else if ([sender state] == UIGestureRecognizerStateEnded)
    {
        CGPoint endPanPoint = [sender locationInView:self];

        float height = fabsf(endPanPoint.y - _startPanPoint.y);
        float width = fabsf(endPanPoint.x - _startPanPoint.x);
        float x = MIN(_startPanPoint.x, endPanPoint.x);
        float y = MIN(_startPanPoint.y, endPanPoint.y);

        MNTRectangle *rectangle = (MNTRectangle *)_currentPanObject;
        [rectangle setFrame:CGRectMake(x, y, width, height)];
    }
}

これについての助けをいただければ幸いです。

4

3 に答える 3

2

私はついにそれを理解しました。handlePan:四角形のフレームを設定した後の私の方法では、行方不明でした[rectangle setNeedsDisplay];

今、私の DocumentView コードは次のようになります。

-(id)initWithFrame:(CGRect)frame
{
   self = [super initWithFrame:frame];

    if (self)
    {
         _panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
    }

    return self;
}

- (void)handlePan:(UIPanGestureRecognizer *)sender
{
   if ([sender state] == UIGestureRecognizerStateBegan)
   {
        _startPanPoint = [sender locationInView:self];

        MNTRectangle *rectangle = [[MNTRectangle alloc] initWithFrame:CGRectMake(_startPanPoint.x, _startPanPoint.y, 1, 1)];
        [_objects addObject:rectangle];
        _currentPanObject = rectangle;
        [self addSubview:rectangle];
    }
    else if ([sender state] == UIGestureRecognizerStateChanged)
    {
        CGPoint endPanPoint = [sender locationInView:self];

        float height = fabsf(endPanPoint.y - _startPanPoint.y);
        float width = fabsf(endPanPoint.x - _startPanPoint.x);
        float x = MIN(_startPanPoint.x, endPanPoint.x);
        float y = MIN(_startPanPoint.y, endPanPoint.y);

        MNTRectangle *rectangle = (MNTRectangle *)_currentPanObject;
        [rectangle setFrame:CGRectMake(x, y, width, height)];
        [rectangle setNeedsDisplay];
    }
    else if ([sender state] == UIGestureRecognizerStateEnded)
    {
        CGPoint endPanPoint = [sender locationInView:self];

        float height = fabsf(endPanPoint.y - _startPanPoint.y);
        float width = fabsf(endPanPoint.x - _startPanPoint.x);
        float x = MIN(_startPanPoint.x, endPanPoint.x);
        float y = MIN(_startPanPoint.y, endPanPoint.y);

        MNTRectangle *rectangle = (MNTRectangle *)_currentPanObject;
        [rectangle setFrame:CGRectMake(x, y, width, height)];
        [rectangle setNeedsDisplay];
    }
}
于 2012-12-08T00:36:04.733 に答える
0

あなたは電話したくなるでしょう[super drawRect:rect]

于 2012-12-07T22:36:05.213 に答える
0

読んでいる人のために明確にするために、[rectangle setNeedsDisplay];オーバーライドしているため呼び出しが必要であり、内部変数が変更された後、 、drawRect:のこのサブクラスに手動で再描画するように指示する必要があります。UIViewMNTRectangle

この関数は、 を継承する標準オブジェクトで自動的に呼び出されますUIViewが、カスタム オブジェクトを作成したMNTRectangleため、 に再描画が必要な特別な動作がある場合は、手動で呼び出す必要があります。

詳細なドキュメントはこちら.

于 2012-12-08T01:03:29.823 に答える