目标:使用图案图像在 Quartz 2D 中进行绘制。目前:
const CGPatternCallbacks kPatternCallbacks = {0, routine, NULL};
void routine(void *info, CGContextRef contextRef) {
UIImage *brushTexture = [UIImage imageNamed:@"PatternImage1"];
CGContextDrawImage(contextRef, CGRectMake(0, 0, 50, 50), brushTexture.CGImage);
}
用于:
CGPatternRef strokePattern = CGPatternCreate(NULL,
CGRectMake(0, 0, 50, 50),
CGAffineTransformIdentity,
50, // horizontal spacing
50, // vertical spacing
kCGPatternTilingNoDistortion,
true,
&kPatternCallbacks);
所有这些东西都在实现类(ViewController.m)中。非常完美,我可以绘制图案图像。
问题:动态更改 C 回调函数内的某些内容,例如:
在“ViewController.h”中
@interface ViewController : UIViewController {
NSString *imageName;
}
@property (nonatomic, strong) NSString *imageName;
以及实现类(ViewController.m)
@synthesize imageName;
imageName = @"PatternImage1";
void routine(void *info, CGContextRef contextRef) {
//UIImage *brushTexture = [UIImage imageNamed:@"PatternImage1"];
//CGContextDrawImage(contextRef, CGRectMake(0, 0, 50, 50), brushTexture.CGImage);
CGContextDrawImage(contextRef, CGRectMake(0, 0, 50, 50), imageName.CGImage);
}
错误!!! -> 使用未声明的标识符“imageName”
我已经尝试过了...
void routine(void *info, CGContextRef contextRef) {
//NSString *imageName = CFBridgingRelease(info); //<- not working
//NSString *imageName = (__bridge NSString *)(info); //<- not working
NSString *imageName = (__bridge NSString *) info; //<- not working
//UIImage *brushTexture = [UIImage imageNamed:@"PatternImage1"];
CGContextDrawImage(contextRef, CGRectMake(0, 0, 50, 50), imageName.CGImage);
}
例程结构不能更改,因为它是由 CGPatternCallbacks 定义的。
void routine(void *info, CGContextRef contextRef) { }
我搜索了很多,但没有找到解决方案。主题如下:
“将 Objective-C 对象传递给 C 函数”
“混合 Objective-C 和 C”
“回调函数”
“C 回调”
什么都没有,什么都没有,什么也没有。
不可能吗?我不这么认为!我将不得不放弃...F***!
最佳答案
传递给回调的 info
参数是您在调用 CGPatternCreate()
时作为 info
参数传递的任何值。在 Objective-C 代码中,您通常会传递 (__bridge void*)self
。然后,在回调中,您将其转换回适当的类型并调用方法来完成实际工作:
void routine(void *info, CGContextRef contextRef) {
ViewController* self = (__bridge ViewController*)info;
[self drawPattern:contextRef];
}
- (void) drawPattern:(CGContextRef)contextRef {
UIImage *brushTexture = [UIImage imageNamed:imageName]; // <- imageName can be an ivar
CGContextDrawImage(contextRef, CGRectMake(0, 0, 50, 50), brushTexture.CGImage);
}
在非常简单的情况下,您只想传递图像名称字符串,您可以将该 NSString*
作为 info
指针传递。或者甚至是根据名称创建的 UIImage*
,这样您就不必每次都创建它。这避免了在恢复的 self
上调用方法的需要。然而,即使您现在的需求很简单,也很容易有更复杂的需求,因此通常值得麻烦地传入 self
。
关于Objective-C 对象转换为 C 回调函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24290044/