目标:使用模式图像在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 Callbacks”
没什么,什么也没有。
不可能?我不这么认为!我将不得不放弃...... F ***!
答案 0 :(得分:2)
传递给回调的info
参数是您在调用info
时作为CGPatternCreate()
参数传递的任何值。在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
通常是值得的。
答案 1 :(得分:0)
找到它!!!
发现iiiiiiiit !!!
static NSString *imageName = @"PatternImage1";
在回调函数中可见!!!!
Yabba Dabba Doo !!!
完整的源代码。只在&#34; ViewController.m&#34; :
#import "ViewController.h"
@implementation ViewController
static NSString *imageName = @"PatternImage1";
在代码的某些部分:
const CGPatternCallbacks kPatternCallbacks = {0, routine, NULL};
在代码的某些部分:
CGPatternRef strokePattern = CGPatternCreate(NULL, CGRectMake(0,0,50,50),
CGAffineTransformIdentity,
50, 50,
kCGPatternTilingNoDistortion,
true,
&kPatternCallbacks);
在代码的某些部分,&#34; if / else&#34;语句:
if () {
imageName = @"PatternImage2";
} else if () {
imageName = @"PatternImage3";
} else {
imageName = @"PatternImage4";
}
最后,回调函数:
void routine(void *info, CGContextRef contextRef) {
UIImage *brushTexture = [UIImage imageNamed:imageName];
CGContextDrawImage(contextRef, CGRectMake(0, 0, 50, 50), brushTexture.CGImage);
}