我在这里有一个有趣的谜语。我的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);
}
答案 0 :(得分:2)
ARC释放名为strokeColor的CGColorRef。一个解决方法是用CGFloat数组替换它并使用CGContextSetStrokeColor而不是CGContextSetStrokeColorWithColor
这个答案解决了这个问题: App crashes when using __bridge for CoreGraphics gradient on ARC
答案 1 :(得分:0)
我同意zeiteisen,ARC发布CGColorRef以及解决此问题的最简单方法
将 strokeColor 的UIColor更改为“RGB CGFloat组件数组”,如下所示:
static CGFloat red, green, blue, alpha;
- (void)getRGBComponents:(CGFloat [4])components forColor:(UIColor *)color {
[color getRed:&red green:&green blue:&blue alpha:&alpha];//To fetch CGFloat RGB components
for (int component = 0; component < 4; component++) {
switch (component) {
case 0:
components[component] = red;
break;
case 1:
components[component] = green;
break;
case 2:
components[component] = blue;
break;
case 3:
components[component] = alpha;
break;
default:
break;
}
}
}
使用这样的方法:
CGFloat components[4];
UIColor *strokeColor=[UIColor greyColor];//My color
[self getRGBComponents:components forColor:strokeColor];//'components' will be substituted in CGContextSetStrokeColor
NSLog(@"%f %f %f %f", components[0], components[1], components[2],components[3]);