gpt4 book ai didi

ios - CGcontext 和 drawRect 不绘图

转载 作者:行者123 更新时间:2023-12-01 18:16:19 25 4
gpt4 key购买 nike

需要一双新的眼睛,我的已经停止工作,无法理解我自己的代码了......

我正在尝试用笔在纸上的绘图风格制作绘图应用程序。以下是它的工作原理:

  • 用户触摸,应用抓取位置
  • 一个 var 设置为告诉 drawRect 配置 CGcontext、创建新路径、移动到点等(因为每当我在 drawRect 方法之外对 CGcontext 进行任何操作时,我总是在我的 nslog 中得到错误/警告)
  • 然后设置 var 来确定当用户抬起手指时是放置点还是线
  • 如果用户拖动,则更改 var 以告诉 drawRect 画一条线,并调用 [self setneedsdisplay]
  • 每次用户将手指放在屏幕上时,都会激活一个计时器,每隔 5 秒(或直到他们抬起手指),应用程序会“捕获”屏幕内容,将其粘贴在图像中并删除屏幕,替换图像和继续绘制(实际上是缓存图像,因此不必重新绘制所有这些行)

  • 更新 #1
    所以我重写了它(因为它显然很糟糕而且不起作用......)并最终得到了这个:
    - (void)drawRect:(CGRect)rect {
    [_incrImage drawInRect:rect]; /* draw image... this will be blank at first
    and then supposed to be filled by the Graphics context so that when the view
    is refreshed the user is adding lines ontop of an image (but to them it looks
    like a continuous drawing)*/
    CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapSquare);
    CGContextSetLineJoin(UIGraphicsGetCurrentContext(), kCGLineJoinRound);
    CGContextSetLineWidth(UIGraphicsGetCurrentContext(), _brushW);
    CGContextSetStrokeColorWithColor(UIGraphicsGetCurrentContext(), [UIColor colorWithRed:_brushR green:_brushG blue:_brushB alpha:_brushO].CGColor);
    CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeNormal);
    CGContextAddPath(UIGraphicsGetCurrentContext(), _pathref);
    CGContextDrawPath(UIGraphicsGetCurrentContext(), kCGPathStroke);
    }

    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    _drw = 2; //set this to draw a dot if the user taps
    UITouch *touch = [touches anyObject];
    _cp = [touch locationInView:self];
    _lp = _cp;
    CGPathRelease(_pathref); /* this line and the line below is to clear the
    path so the app is drawing as little as possible (the idea is that as
    the user draws and lifts their finger, the drawing goes into _incrImage
    and then the contents is cleared and _incrImage is applied to the
    screen so there is as little memory being used as possible and so the
    user feels as if they're adding to what they've drawn when they touch
    the device again) */
    _pathref = CGPathCreateMutable();
    CGPathMoveToPoint(_pathref, NULL, _lp.x, _lp.y);
    touch = nil;
    }

    - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    _drw = 1; //user moved their finger, this was not a tap so they want
    //to draw a line
    UITouch *touch = [touches anyObject];
    _cp = [touch locationInView:self];
    CGPathAddLineToPoint(_pathref, NULL, _cp.x, _cp.y);
    [self setNeedsDisplay]; //as the user moves their finger, it draws
    _lp = _cp;
    touch = nil;
    }

    - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    _cp = [touch locationInView:self];
    switch (_drw) { //logic to determine what to draw when the user
    //lifts their finger
    case 1:
    //line
    CGPathAddLineToPoint(_pathref, NULL, _cp.x, _cp.y);

    break;
    case 2:
    //dot
    CGPathAddArc(_pathref, NULL, _cp.x, _cp.y, _brushW, 0.0, 360.0, 1);

    break;

    default:
    break;
    }
    /* here's the fun bit, the Graphics context doesn't seem to be going
    into _incrImage and therefore is not being displayed when the user
    goes to continue drawing after they've drawn a line/dot on the screen */
    UIGraphicsBeginImageContext(self.frame.size);
    CGContextAddPath(UIGraphicsGetCurrentContext(), _pathref); /* tried adding
    my drawn path to the context and then adding the context to the image
    before the user taps down again and the path is cleared... not sure
    why it isn't working. */
    [_incrImage drawAtPoint:CGPointZero];
    _incrImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    [self setNeedsDisplay]; //finally, refresh the contents
    touch = nil;
    }

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

    我的新问题是调用drawRect时所有内容都被删除了,并且'_incrImage'没有获取当前图形的内容并显示它们

    __old,我想不再需要,但留在这里供引用___

    这是相关代码:
    - (void)drawRect:(CGRect)rect {
    /* REFERENCE: _drw: 0 = clear everything
    1 = cache the screen contents in the image and display that
    so the device doesn't have to re-draw everything
    2 = set up new path
    3 = draw lines instead of a dot at current point
    4 = draw a 'dot' instead of a line
    */
    CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapSquare);
    CGContextSetLineJoin(UIGraphicsGetCurrentContext(), kCGLineJoinRound);
    CGContextSetLineWidth(UIGraphicsGetCurrentContext(), _brushW);
    CGContextSetStrokeColorWithColor(UIGraphicsGetCurrentContext(), [UIColor colorWithRed:_brushR green:_brushG blue:_brushB alpha:_brushO].CGColor);
    CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeNormal);

    switch (_drw) {
    case 0:
    //clear everything...this is the first draw... it can also be called to clear the view
    UIGraphicsBeginImageContext(self.frame.size);
    CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeClear);
    CGContextSetFillColorWithColor(UIGraphicsGetCurrentContext(), [UIColor clearColor].CGColor);
    CGContextFillRect(UIGraphicsGetCurrentContext(), self.frame);
    CGContextFlush(UIGraphicsGetCurrentContext());
    _incrImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    [_incrImage drawAtPoint:CGPointZero];
    [_incrImage drawInRect:rect];
    break;
    case 1:
    //capture the screen content and stick it in _incrImage...
    then apply_incrImage to screen so the user can continue drawing ontop of it
    _incrImage = UIGraphicsGetImageFromCurrentImageContext();
    [_incrImage drawAtPoint:CGPointZero];
    [_incrImage drawInRect:rect];
    break;
    case 2:
    //begin path and set everything up, this is called when touchesBegan: fires...
    _incrImage = UIGraphicsGetImageFromCurrentImageContext();
    [_incrImage drawAtPoint:CGPointZero];
    [_incrImage drawInRect:rect];
    CGContextBeginPath(UIGraphicsGetCurrentContext());
    CGContextMoveToPoint(UIGraphicsGetCurrentContext(), _p.x, _p.y);
    break;
    case 3:
    //add lines, this is after the path is created and set...this is fired when touchesMoved: gets activated and _drw is set to draw lines instead of adding dots
    CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), _p.x, _p.y);
    CGContextStrokePath(UIGraphicsGetCurrentContext());
    break;
    case 4:
    //this is fired when touchesEnd: is activated... this sets up ready if the app needs to draw a 'dot' or the arc with a fill...
    CGContextMoveToPoint(UIGraphicsGetCurrentContext(), _p.x, _p.y);
    CGContextAddArc(UIGraphicsGetCurrentContext(), _p.x, _p.y, _brushW, 0.0, 360.0, 1);
    CGContextFillPath(UIGraphicsGetCurrentContext());
    CGContextFlush(UIGraphicsGetCurrentContext());
    break;

    default:
    break;
    }
    }
    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    dTimer = [NSTimer timerWithTimeInterval:5.0 target:self selector:@selector(timeUP) userInfo:Nil repeats:YES];
    _drw = 2;
    UITouch *touch = [touches anyObject];
    _p = [touch locationInView:self];
    [self setNeedsDisplay];
    _drw = 4;
    }
    - (void)timeUP {
    _drw = 1;
    [self setNeedsDisplay];
    }
    - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    _drw = 3;
    UITouch *touch = [touches anyObject];
    _p = [touch locationInView:self];
    [self setNeedsDisplay];
    }
    - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event // (2)
    {
    [dTimer invalidate];
    UITouch *touch = [touches anyObject];
    _p = [touch locationInView:self];
    [self setNeedsDisplay];
    [self timeUP];
    }
    - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
    [self touchesEnded:touches withEvent:event];
    }

    我的问题是:
  • 这是有效的吗?还是有更好的方法来做到这一点?
  • 这个怎么不画了?我什么也没得到,但我可以看到我的内存正在被使用...
  • 最佳答案

    埃加德。

    你的第一个问题是 setNeedsDisplay不会立即绘制,它只是标记要在事件结束时绘制的 View 。因此,当您设置 _drw=2 并调用 setNeedsDisplay然后设置_drw=4,它只会实际调用-drawRect:使用 _drw=4 (如果那样的话,因为那可能还不是当前事件的结束)。

    但是,也不要,呃,使用那个 _drw 开关的东西。这不好。

    您想创建一个图像并在触摸发生时绘制到图像中,然后在 drawRect: 中将图像拉到屏幕上。如果你发现自己在 -drawRect; 中调用 UIGraphicsGetImageFromCurrentImageContext()您正在倒退(就像您在这里一样)。不要从屏幕上啜饮图像,创建一个你吹到屏幕上的图像。

    屏幕永远不应该是你的“状态”。那就是疯狂。

    关于ios - CGcontext 和 drawRect 不绘图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21671712/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com