6

这是我想要做的:

我有一个 UIBezierPath,我想将它传递给一些方法来绘制它。或者简单地从创建它的方法中绘制它。

我不确定如何指示它应该在哪个视图中绘制。是否所有绘图方法都必须从

- (void)drawRect:(CGRect)rect { ...} ?

我可不可以做

- (void)drawRect:(CGRect)rect withBezierPath:(UIBezierPath*) bezierPath { ... } ??

如何从另一个方法调用此函数或方法?

4

5 回答 5

20

drawRect: is something that is invoked automatically when you message setNeedsDisplay or setNeedsDisplayInRect: on a view. You never call drawRect: directly.

However you are right in saying that all drawing operations are done within the drawRect: method. Typical implementation would be,

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

    /* Do your drawing on `context` */
}

Since you are using UIBezierPaths, you will need to maintain an array of bezier paths that you will need to draw and then call setNeedsDisplay when something changes.

- (void)drawRect:(CGRect)rect {    
    for ( UIBezierPath * path in bezierPaths ) {
        /* set stroke color and fill color for the path */
        [path fill];
        [path stroke];
    }
}

where bezierPaths is an array of UIBezierPaths.

于 2011-06-22T05:01:09.760 回答
6

首先,将路径保存在 ivar 中

@interface SomeView {
  UIBezierPath * bezierPath;
}
@property(nonatomic,retain) UIBezierPath * bezierPath;
...
@end
....
- (void)someMethod {
     self.bezierPath = yourBezierPath;
     [self setNeedsDisplayInRect:rectToRedraw];
}

在-drawRect:

- (void)drawRect:(CGRect)rect {
    CGContextRef currentContext = UIGraphicsGetCurrentContext();
    CGContextSetLineWidth(currentContext, 3.0);
    CGContextSetLineCap(currentContext, kCGLineCapRound);
    CGContextSetLineJoin(currentContext, kCGLineJoinRound);
    CGContextBeginPath(currentContext);
    CGContextAddPath(currentContext, bezierPath.CGPath);
    CGContextDrawPath(currentContext, kCGPathStroke);
}
于 2011-06-22T04:59:37.050 回答
3

当您需要自定义视图时,可以覆盖-drawRect:子类:

- (void)drawRect:(CGRect)rect
{
  // config your context
  [bezierPath stroke];
}

编辑:直接使用-stroke使代码更紧凑。

于 2011-06-22T04:53:39.757 回答
1

Drawing only happens inside a method called -drawRect: (which is automatically called when a view is marked as needing display via setNeedsDisplay). So a drawRect:withBezierPath: method will never get invoked automatically. The only way it will execute is if you call it yourself.

Once you have a UIBezierPath, however, it's very easy to draw it:

- (void)drawRect:(CGRect)rect {
  UIBezierPath *path = ...; // get your bezier path, perhaps from an ivar?
  [path stroke];
}

There's no need to futz around with Core Graphics if all you want to do is draw a path.

于 2011-06-22T05:00:32.573 回答
1

you can do something like following. just define a UIColor *setStroke; in .h file and you need to set this strokeColor object before your you call [myPath strokeWithBlendMode:kCGBlendModeNormal alpha:1.0];

 - (void)drawRect:(CGRect)rect
    {
        [strokeColor setStroke]; // this method will choose the color from the receiver color object (in this case this object is :strokeColor)
        for(UIBezierPath *_path in pathArray)
            [myPath strokeWithBlendMode:kCGBlendModeNormal alpha:1.0];
    }

    #pragma mark - Touch Methods
    -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
    {
        myPath=[[UIBezierPath alloc]init];
        myPath.lineWidth = currentSliderValue;

        UITouch *mytouch=[[touches allObjects] objectAtIndex:0];
        [myPath moveToPoint:[mytouch locationInView:self]];
        [pathArray addObject:myPath];
    }
    -(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
    {
        UITouch *mytouch=[[touches allObjects] objectAtIndex:0];
        [myPath addLineToPoint:[mytouch locationInView:self]];
        [self setNeedsDisplay];

    }
于 2012-11-27T08:04:08.510 回答