【问题标题】:Is it possible to draw Graphics with CGContext and save them into a NSMutableArray?是否可以使用 CGContext 绘制图形并将它们保存到 NSMutableArray 中?
【发布时间】:2012-06-04 08:05:34
【问题描述】:

一开始我画图形:

    -(void)drawRect: (CGRect)rect{  

        //Circle
    circle = UIGraphicsGetCurrentContext();  
    CGContextSetFillColorWithColor(circle, [UIColor darkGrayColor].CGColor);
    CGContextFillRect(circle,CGRectMake(10,10, 50, 50));

        //rectangle
    rectangle = UIGraphicsGetCurrentContext();  
    CGContextSetFillColorWithColor(rectangle, [UIColor darkGrayColor].CGColor);
    CGContextFillRect(rectangle, CGRectMake(10, 10, 50, 50));

        //square 
    square = UIGraphicsGetCurrentContext();  
    CGContextSetFillColorWithColor(square, [UIColor darkGrayColor].CGColor);
    CGContextFillRect(square, CGRectMake(100, 100, 25, 25));

        //triangle  
    triangle = UIGraphicsGetCurrentContext(); 
    CGContextSetFillColorWithColor(triangle, [UIColor darkGrayColor].CGColor);
    CGPoint points[6] = { CGPointMake(100, 200), CGPointMake(150, 250),
                              CGPointMake(150, 250), CGPointMake(50, 250),
                              CGPointMake(50, 250), CGPointMake(100, 200) };
    CGContextStrokeLineSegments(triangle, points, 6);

    }

现在我想将图形放入一个数组中:

-(void)viewDidLoad {

grafics = [[NSMutableArray alloc]initWithObjects: circle,rectangle,square,triangle];
[self.navigationItem.title = @"Shape"];
[super viewDidLoad];
}

问题是,我必须进行强制转换,从而使对象适合这个数组。另一个问题是 UITableViewController 不会将数组加载到行中。 tableview 没有问题,但处理 CGContext 失败。我做错了什么?

【问题讨论】:

    标签: objective-c ios nsmutablearray cgcontext cgcontextdrawimage


    【解决方案1】:

    drawRect:UIView 上的一个方法,用于绘制视图本身,而不是预先创建图形对象。

    由于您似乎想要创建形状来存储它们并稍后绘制,因此将形状创建为UIImage 并使用UIImageView 绘制它们似乎是合理的。 UIImage 可以直接存储在NSArray 中。

    要创建图像,请执行以下操作(在主队列中;不在 drawRect 中:):

    1) 创建位图上下文

    UIGraphicsBeginImageContextWithOptions(size, opaque, scale);
    

    2) 获取上下文

    CGContextRef context = UIGraphicsGetCurrentContext();
    

    3) 画出你需要的任何东西

    4) 将上下文导出到图像中

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    

    5) 销毁上下文

    UIGraphicsEndImageContext();
    

    6) 存储对图像的引用

    [yourArray addObject:image];
    

    对您要创建的每个形状重复此操作。

    有关上述功能的详细信息,请参阅documentation。为了更好地了解在drawRect: 中绘图与在程序中的任意位置绘制以及使用一般上下文之间的区别,我建议您阅读Quartz2D Programming Guide,尤其是有关图形上下文的部分。

    【讨论】:

    • “主队列”是什么意思?你的意思是函数:viewDidLoad?
    • 不,只是不要使用 Grand Central Dispatch 在另一个队列上运行此代码。 UIKit 对象和函数不应该在其他队列上使用,因为它们不是线程安全的。默认情况下,您的所有代码都在主队列上运行。
    【解决方案2】:

    首先,UIGraphicsGetCurrentContext 返回CGContextRef,它不是对象,不能直接存储在集合中(edit: 这不是真的,请参阅 cmets)。从技术上讲,您可以将上下文包装在 NSValue 中或将其转换为 UIImage

    CGImageRef imageRef = CGBitmapContextCreateImage(context);
    UIImage *img = [UIImage imageWithCGImage:imageRef];
    

    生成的UIImage 是一个对象,可以很好地存储在集合中。 但是代码示例在大局中没有意义。 -drawRect: 方法旨在绘制您的组件,而不是创建一些稍后使用的图形。而-viewDidLoadUIViewController 方法,而不是UIView 方法。您能否编辑问题并描述您要做什么?

    【讨论】:

    • CGContextRef 可以存储在 iOS 上的 NSArray(或 NSMutableArray)中。 CFType 的所有“子类”都响应 retainrelease。见cocoabuilder.com/archive/cocoa/…
    • 我忘了桥接,你说得对。 (另一个来源是previous SO question。)因此,将上下文存储到数组中的最简单方法是简单地强制转换,但其余答案应该仍然有效。
    猜你喜欢
    • 1970-01-01
    • 2021-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多