【问题标题】:How to create two strokes of different color using one UIBezierPath如何使用一个 UIBezierPath 创建两个不同颜色的笔画
【发布时间】:2015-10-13 16:52:22
【问题描述】:

我正在尝试用手指在UIView 上画线,并且用一种颜色效果很好。如果我尝试更改颜色并重新绘制,之前的UIBezierPath 颜色也会更改为新颜色。所以,我无法在UIView 上绘制一条保持先前颜色线的不同颜色线

我在UIView 中将所有属性(路径、线条颜色)设置为非原子且强的

供参考:

我的第一次抽奖:

我的第二次抽奖:

我的第三次抽奖:

选择颜色后,我在颜色选择器委托方法中更改 UIView 的笔触颜色:

#pragma mark - FCColorPickerViewControllerDelegate Methods

-(void)colorPickerViewController:(FCColorPickerViewController *)colorPicker didSelectColor:(UIColor *)color {

      self.drawView.lineColor = color; //this works fine 

 //    self.drawView.path=[UIBezierPath bezierPath];  tried this to create new bezier path with new color, but this erases the olde bezier path and return new
//    [self.drawView.lineColor setStroke];     tried this
//    [self.drawView.lineColor setFill];  tried this

      [self dismissViewControllerAnimated:YES completion:nil]; //dismiss the color picker
}

这是我的绘图视图方法:

- (id)initWithCoder:(NSCoder *)aDecoder 
{
    if (self = [super initWithCoder:aDecoder])
    {
        [self setBackgroundColor:[UIColor whiteColor]];
        path = [UIBezierPath bezierPath];
        [path setLineWidth:self.lineWidth];
    }
    return self;
}

- (void)drawRect:(CGRect)frame 
{
    [self.lineColor setStroke];

    [path stroke];

}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    dispatch_async(dispatch_get_main_queue(), ^{
        UITouch *touch = [touches anyObject];
        CGPoint p = [touch locationInView:self];
        [path moveToPoint:p];
    });

}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
   dispatch_async(dispatch_get_main_queue(), ^{
       UITouch *touch = [touches anyObject];
       CGPoint p = [touch locationInView:self];
       [path addLineToPoint:p];
       [self setNeedsDisplay];
   });
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    [self touchesMoved:touches withEvent:event];
}

我尝试this: 将旧的贝塞尔路径添加到数组中并重绘它们,但没有奏效,这次我无法使用新颜色制作另一个贝塞尔路径。:

       - (void)drawRect:(CGRect)frame // (5)
{
    //load the path from array
    for (int i = 0; i < [pathArray count]; i++){


        NSLog(@"Path: %@",[pathArray objectAtIndex:0]);
        NSLog(@"Color: %@",[pathArray objectAtIndex:1]);

        UIBezierPath *oldpath = [pathArray objectAtIndex:0];

         //color
        [[pathArray objectAtIndex:1] setStroke];

        //path
        [oldpath stroke];
    }

    UIBezierPath *newPath = [self pathForCurrentLine];
    if (newPath)
    {
        // set the width, color, etc, too, if you want
         [lineColor setStroke];
        [newPath stroke];
    }

}

   - (UIBezierPath*)pathForCurrentLine {
    if (CGPointEqualToPoint(startPoint, CGPointZero) && CGPointEqualToPoint(endPoint, CGPointZero)){
        return nil;
    }

    UIBezierPath *newpath = [UIBezierPath bezierPath];
    [newpath moveToPoint:startPoint];
    [newpath addLineToPoint:endPoint];

    return newpath;

}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    dispatch_async(dispatch_get_main_queue(), ^{
        UITouch *touch = [touches anyObject];
        CGPoint p = [touch locationInView:self];
        [path moveToPoint:p];
        startPoint=p;
    });

}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
   dispatch_async(dispatch_get_main_queue(), ^{
       UITouch *touch = [touches anyObject];
       CGPoint p = [touch locationInView:self];
       [path addLineToPoint:p]; // (4)
       endPoint=p;

       [self setNeedsDisplay];
   });
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    [self touchesMoved:touches withEvent:event];

    [pathArray addObject:path];
    [pathArray addObject:lineColor];

}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
    [self touchesEnded:touches withEvent:event];
}

【问题讨论】:

  • 您应该在每次用户抬起手指或每次更改颜色时创建一条全新的贝塞尔路径。

标签: ios objective-c uiview uibezierpath


【解决方案1】:

你实际上不能用不同的颜色描边同一路径的不同部分。

您可以将绘图上下文视为一个状态机。每次您发出绘图命令(例如在UIBezierPath 上调用stroke)时,它都会检查当前的笔触/填充颜色并使用它来执行绘图。要创建不同颜色的多个笔触,您需要有多个笔触路径,并在每次调用 stroke 之间设置笔触颜色。

- (void)drawRect:(CGRect)frame {
    UIBezierPath* pathOne = // create path one
    UIBezierPath* pathTwo = // create path two
    UIBezierPath* pathThree = // create path three

    [[UIColor redColor] setStroke];
    [pathOne stroke];

    [[UIColor greenColor] setStroke];
    [pathTwo stroke];

    [[UIColor blueColor] setStroke];
    [pathThree stroke];
}

【讨论】:

  • 如果我创建一个新的贝塞尔路径,我的旧路径会怎样?我将 bezierpath 声明为属性。我需要将该属性设置为新路径吗?请举个例子
  • Overtime drawRect: 被调用,您必须重绘所有需要在屏幕上显示的内容。如果您需要保留旧路径,则必须保留每次调用 drawRect: 时都会绘制的路径数组。
  • 另外,你需要实现touchesCancelled:withEvent:,即使它只是和touchesEnded:withEvent:做同样的事情。如果您实现其中任何一个,那么实现所有四个UIResponder 触摸处理方法非常重要,这样超级视图就不会获得部分触摸方法调用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-11-25
  • 1970-01-01
  • 2023-02-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-03
相关资源
最近更新 更多