【问题标题】:calling drawRect in a UIView subclass在 UIView 子类中调用 drawRect
【发布时间】:2012-02-23 04:27:24
【问题描述】:

我对 UIView 进行了子类化,并实现了 drawRect。我基本上希望在我设置了 CGPoint 之后调用这个 drawRect,这是这​​个 UIView 的一个属性。我该怎么做呢?这是我的代码:

-(id) initWithCoder:(NSCoder *)aDecoder
{
    if(self = [super initWithCoder:aDecoder]) {
        point_.x = 0;
        self.page_ = [UIImage imageNamed:@"pages"];
    }
    return self;
}

// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
    if (point_.x != 0){
        [self.page_ drawInRect:rect];
        CGContextRef context = UIGraphicsGetCurrentContext();
        CGContextSetStrokeColorWithColor(context, [UIColor blackColor].CGColor);
        CGContextSetLineWidth(context, 1.0f);
        CGContextMoveToPoint(context, 40, point_.y); 
        CGContextAddLineToPoint(context, 420, point_.y);
        CGContextStrokePath(context);
    }
}

当我设置了这个 UIView 的点并在我的另一个 UIViewController 中调用 drawRect 时,如下所示:

 self.page_.point_ = CGPointMake(-100, self.title_.frameHeight + self.title_.frameX + 40);
    [self.page_ drawRect:self.page_.frame];

它给了我所有这些错误:

  <Error>: CGContextSaveGState: invalid context 0x0
    Feb 22 20:24:38 <Error>: CGContextSetBlendMode: invalid context 0x0
    Feb 22 20:24:38 <Error>: CGContextSetAlpha: invalid context 0x0
    Feb 22 20:24:38 <Error>: CGContextTranslateCTM: invalid context 0x0
    Feb 22 20:24:38 <Error>: CGContextScaleCTM: invalid context 0x0
    Feb 22 20:24:38 <Error>: CGContextDrawImage: invalid context 0x0
    Feb 22 20:24:38 <Error>: CGContextRestoreGState: invalid context 0x0
    Feb 22 20:24:38 <Error>: CGContextSetStrokeColorWithColor: invalid context 0x0
    Feb 22 20:24:38 <Error>: CGContextSetLineWidth: invalid context 0x0
    Feb 22 20:24:38 <Error>: CGContextMoveToPoint: invalid context 0x0
    Feb 22 20:24:38 <Error>: CGContextAddLineToPoint: invalid context 0x0
    Feb 22 20:24:38 <Error>: CGContextDrawPath: invalid context 0x0

这是为什么?

【问题讨论】:

    标签: iphone objective-c ios ipad


    【解决方案1】:

    你永远不应该直接致电-drawRect:

    改用-setNeedsDisplay

    self.page_.point_ = CGPointMake(-100, self.title_.frameHeight + self.title_.frameX + 40);
    [self.page_ setNeedsDisplay];
    

    如果您需要自定义绘图区域(也就是将传递给-drawRect:CGRect),您可以使用-setNeedsDisplayInRect:

    正如@rob mayoff 所建议的,您可以覆盖point_ 属性的设置器:

    - (void)setPoint_:(CGPoint)point {
       if(!CGPointEqualToPoint(point_, point)) {
          point_ = point;
          [self setNeedsDisplay];
       }
    }
    

    【讨论】:

    • 如果point_ 的值确实发生了变化,最好让point_ 属性设置器调用setNeedsDisplay
    • aha..这是个好主意..所以在我的 setteer 中我会调用 setNeedsDisplay。介意解释一下为什么这样更好吗?
    【解决方案2】:
    - (id)initWithCoder:(NSCoder *)aDecoder // (1)
    {
    if (self = [super initWithCoder:aDecoder])
    {
        [self setMultipleTouchEnabled:NO]; // (2)
        [self setBackgroundColor:[UIColor whiteColor]];
        path = [UIBezierPath bezierPath];
        [path setLineWidth:2.0]; 
    }
    return self;
    }
    
    
    - (void) drawRect:(CGRect)rect
    {
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetRGBStrokeColor(context, 0.0, 0.0, 0.0, 1.0);
    CGContextSetLineWidth(context, 3.0);
    CGContextDrawPath(context, kCGPathFillStroke);    //CGContextSetRGBFillColor doesn't work either
    CGContextBeginPath(context);
    CGContextMoveToPoint(context, 100.0, 60.0);
    CGRect rectangle = {100.0, 60.0, 120.0, 120.0};
    CGContextAddRect(context, rectangle);
    
    CGContextStrokePath(context);
    CGContextFillPath(context);
    }
    this code implement in create new uiview and add this code i hope that code you usefull.
    

    【讨论】:

      【解决方案3】:

      将您的绘图代码封装到 UIGraphicsPushContext( context )UIGraphicsPopContext() 以避免出现此错误消息。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-11-22
        • 1970-01-01
        相关资源
        最近更新 更多