gpt4 book ai didi

手势处理程序中的iOS绘图上下文NULL

转载 作者:行者123 更新时间:2023-12-01 18:13:50 24 4
gpt4 key购买 nike

我在尝试绘制 iOS 以响应 Gesture 事件时遇到了麻烦,我确信这是因为我可能错过了一些不明显的基本 iOS 编程概念。

无论如何,当代码响应事件执行时,UIGraphicsGetCurrentContext() 似乎返回 NULL。我不明白为什么。其他绘图代码,在 View 的 drawRect 方法中,工作得很好。

我可以看到事件正在被触发,因为我正在记录它。只是 UIGraphicsGetCurrentContext 在执行内部事件处理代码时返回 null(即使该代码是 View 类中设置事件处理的函数?

此外,还会记录此错误:

<Error>: CGContextSetFillColorWithColor: invalid context 0x0. This is a serious error. This application, or a library it uses, is using an invalid context  and is thereby contributing to an overall degradation of system stability and reliability. This notice is a courtesy: please fix this problem. It will become a fatal error in an upcoming update.

这是相关的代码位,我希望有一些明显的东西:
@implementation MainView: UIView

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

- (void)setupEvents {
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc]
initWithTarget:self
action:@selector(showGestureForTapRecognizer:)];
tapRecognizer.numberOfTapsRequired = 1;
[self addGestureRecognizer:tapRecognizer];
}

- (IBAction)showGestureForTapRecognizer:(UITapGestureRecognizer *)recognizer {

// Get the location of the gesture
CGPoint location = [recognizer locationInView:self];
NSLog(@"got a tap at (%f,%f)", location.x, location.y);
[self drawCircleX:location.x Y:location.y Radius:5 Color:([UIColor blackColor].CGColor)];
}

- (void) drawCircleX:(int)x Y:(int)y Radius:(int)radius Color:(CGColorRef)fillColor
{
CGContextRef context = UIGraphicsGetCurrentContext(); // null if called from event handler
NSLog(@"context=0x%08lx", context);
// CGContextSaveGState(context);
CGRect rect = CGRectMake(x-radius,y-radius, radius*2, radius*2);
CGContextSetFillColorWithColor(context, fillColor);
CGContextFillEllipseInRect(context, rect);
// CGContextRestoreGState(context);
}

我花了好几天的时间试图弄清楚这一点,阅读了大量的文档,但无济于事。是什么赋予了? (ios新手)

最佳答案

在 iOS 上绘图并不像您认为的那样工作。你不能随心所欲地画画。你必须告诉 UIKit 需要重新绘制一些东西,然后,在 future 的某个时间点,它会开始绘制并且你的绘制代码会被执行。

它以这种方式工作的原因很简单:如果您要绘制的圆圈顶部当前有其他东西怎么办?这意味着你不能只重画你的圆圈,必须同时重画另一件事——因为它可能有抗锯齿或需要知道它下面是什么的东西。

所以,在 showGestureForTapRecognizer 结尾,只需这样做:

[self setNeedsDisplayInRect:...rect that needs display...];

或者(如果你不介意弄清楚矩形):
[self setNeedsDisplay];

然后实现drawRect:
- (void)drawRect:(CGRect)rect
{
// do your drawing here
}

最后......这是实现 View 绘制的“旧”方法。它有严重的性能问题,尤其是在 ARM 处理器上。

你真正应该做的是创建一系列 CALayer 对象(例如, CAShapeLayer 来创建一个椭圆),这些对象将自己绘制。你继承 CALayer 并实现 drawInContext:如果没有内置类。这是现代方法,可能比您正在寻找的更复杂。但它是更好的选择,因为它具有更好的性能并且很好地支持动画。

如果您曾经使用过 HTML/CSS 或使用过 SVG,那与 CALayer 的工作方式大致相同。你有一个嵌套的东西树将被绘制到屏幕上,你修改数据而不是直接绘制到 GPU。

关于手势处理程序中的iOS绘图上下文NULL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24976196/

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