我在这里找到了一个有趣的谜语。我的 cocos2d 项目使用 UIView 来显示比常规警报视图更好的弹出窗口。为了在弹出窗口的大小上更加灵活,我在 drawRect 方法中绘制了背景。
但首先是我如何实现 cocos2d 和 UIKit 的层次结构:
每个 UIKit 元素都被添加到 RootViewController。每个 CCNode 到 EAGLView。(如果有人有更好的解决方案来混合这些世界,请不要等待告诉我!)不幸的是每个 UIKit 视图都在 cocos 节点前面。
当我将第一个弹出窗口添加到 RootViewController 时,一切正常。但是,如果我删除第一个弹出窗口并向 RootViewController 添加新的弹出窗口,则会发生错误访问。它仅在与 cocos2d 结合使用时才会崩溃。
我使用 Ray Wenderlichs CoreGraphics 101 教程中的代码。
context 和 strokeColor 不为零。另一个重要信息:我使用 ARC 并且支持 iOS 4.2 及更高版本。
完整的代码可以在 raywenderlich.com 或下面找到
void drawLinearGradient(CGContextRef context, CGRect rect, CGColorRef startColor, CGColorRef endColor)
{
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGFloat locations[] = { 0.0, 1.0 };
NSArray *colors = [NSArray arrayWithObjects:(__bridge id)startColor, (__bridge id)endColor, nil];
CGGradientRef gradient = CGGradientCreateWithColors(colorSpace,
(__bridge CFArrayRef) colors, locations);
CGPoint startPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMinY(rect));
CGPoint endPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMaxY(rect));
CGContextSaveGState(context);
CGContextAddRect(context, rect);
CGContextClip(context);
CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0);
CGContextRestoreGState(context);
CGGradientRelease(gradient);
CGColorSpaceRelease(colorSpace);
}
CGRect rectFor1PxStroke(CGRect rect)
{
return CGRectMake(rect.origin.x + 0.5, rect.origin.y + 0.5, rect.size.width - 1, rect.size.height -1);
}
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGRect frame = CGRectInset(self.bounds, 2, 2);
CGContextSetShadowWithColor(context, CGSizeMake(0, 0), 3.0, shadowColor);
CGRect strokeRect = CGRectInset(frame, -2.0, -2.0);
CGContextSetStrokeColorWithColor(context, strokeColor);
CGContextSetLineWidth(context, 2.0);
CGContextStrokeRect(context, rectFor1PxStroke(strokeRect));
drawLinearGradient(context, frame, gradient1, gradient2);
}