Ios React Native Bridge-在Objective-C中导出另一个文件中的一个函数
在Ios React Native Bridge-在Objective-C中导出另一个文件中的一个函数,ios,objective-c,react-native,react-native-ios,Ios,Objective C,React Native,React Native Ios,在CMIconManager.m中,我有一个名为getImageForIcon的函数 - (UIImage *)getImageForIcon:(CMIcon)icon fontSize:(CGFloat)fontSize fontColor:(UIColor *)fontColor imageWidth:(CGFloat)imageWidth imageHeight:(CGFloat)imageHeight backgroundCircleColor:(UIColor *)backgrou
CMIconManager.m
中,我有一个名为getImageForIcon
的函数
- (UIImage *)getImageForIcon:(CMIcon)icon fontSize:(CGFloat)fontSize fontColor:(UIColor *)fontColor imageWidth:(CGFloat)imageWidth imageHeight:(CGFloat)imageHeight backgroundCircleColor:(UIColor *)backgroundCircleColor backgroundCircleSize:(CGFloat)backgroundCircleSize {
// set up the squares we will be drawing in...
CGSize imageSize = CGSizeMake(imageWidth, imageHeight);
CGRect imageRect = CGRectMake(0, 0, imageSize.width, imageSize.height);
CGSize circleSize = CGSizeMake(backgroundCircleSize, backgroundCircleSize);
CGRect circleRect = CGRectMake((imageWidth - backgroundCircleSize) / 2, (imageHeight - backgroundCircleSize) / 2, circleSize.width, circleSize.height);
// start the drawing context...
UIGraphicsBeginImageContextWithOptions(imageSize, NO, [[UIScreen mainScreen] scale]);
CGContextRef ctx = UIGraphicsGetCurrentContext();
// fill the image background with transparent alpha...
CGContextScaleCTM(ctx, 1, -1);
CGContextTranslateCTM(ctx, 0, -imageRect.size.height);
CGContextSetAlpha(ctx, 0.0);
CGContextFillRect(ctx, CGRectMake(0, 0, imageSize.width, imageSize.height));
// reset subsequent drawing to non-transparent...
CGContextSetAlpha(ctx, 1.0);
// fill in a solid background circle, centered, if needed...
if (![backgroundCircleColor isEqual:[UIColor clearColor]] || !backgroundCircleColor) {
CGContextSetLineWidth(ctx, 1.0);
CGContextSetFillColorWithColor(ctx, backgroundCircleColor.CGColor);
CGContextFillEllipseInRect(ctx, circleRect);
}
// draw the icon, centered in the image...
if ([fontColor isEqual:[UIColor clearColor]]) {
CGContextSetBlendMode(ctx, kCGBlendModeClear);
}
NSAttributedString *theString = [self attributedStringForIcon:icon fontSize:fontSize color:fontColor];
if (theString.length >= 1) {
CTFramesetterRef frameSetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef) (theString));
CGFloat widthConstraint = imageWidth;
CGSize suggestedSize = CTFramesetterSuggestFrameSizeWithConstraints(frameSetter, CFRangeMake(0, theString.length), NULL, CGSizeMake(widthConstraint, CGFLOAT_MAX), NULL);
CGFloat distanceFromTop = (imageWidth - suggestedSize.height) / 2;
CGFloat distanceFromLeft = (imageHeight - suggestedSize.width) / 2;
CGMutablePathRef path = CGPathCreateMutable();
CGPathAddRect(path, NULL, CGRectMake(distanceFromLeft, distanceFromTop, suggestedSize.width, suggestedSize.height));
CTFrameRef frame = CTFramesetterCreateFrame(frameSetter, CFRangeMake(0, 0), path, NULL);
CTFrameDraw(frame, ctx);
CFRelease(frame);
CFRelease(path);
CFRelease(frameSetter);
}
// save the current context in a UIImage object...
UIImage *finalImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return finalImage;
}
如何将此函数传递到新文件:
RNIconManager.m
中的RCT\u EXPORT\u METHOD()
#import "RNIconManager.h"
#import "CMIconManager.h"
@implementation RNIconManager
RCT_EXPORT_MODULE();
CMIconManager *getIcons = [[CMIconManager alloc] init];
RCT_EXPORT_METHOD(getImageForIcon:(UIImage*)icon
fontSize:(CGFloat)fontSize
fontColor:(UIColor *)fontColor
imageWidth:(CGFloat)imageWidth
imageHeight:(CGFloat)imageHeight
backgroundCircleColor:(UIColor *)backgroundCircleColor
backgroundCircleSize:(CGFloat)backgroundCircleSize
callback:(RCTResponseSenderBlock) callback)
{
callback(@[getIcons(icon, fontSize, fontColor,imageWidth, imageHeight, backgroundCircleColor, backgroundCircleSize)]);
}
RCT\u EXPORT\u方法
宏将整个方法签名作为一个参数,因此它看起来像这样:
RCT_EXPORT_METHOD(getImageForIcon:(UIImage*)icon
fontSize:(CGFloat)fontSize
fontColor:(UIColor *)fontColor
imageWidth:(CGFloat)imageWidth
imageHeight:(CGFloat)imageHeight
backgroundCircleColor:(UIColor *)backgroundCircleColor
backgroundCircleSize:(CGFloat)backgroundCircleSize)
{
//your function content goes here
}
几个注意事项:
CMIcon
//in your h file
@interface CMIconManager : NSObject
+ (UIImage*)getImageForIcon:(UIImage*)icon fontSize:(CGFloat)fontSize fontColor:(UIColor *)fontColor imageWidth:(CGFloat)imageWidth imageHeight:(CGFloat)imageHeight backgroundCircleColor:(UIColor *)backgroundCircleColor backgroundCircleSize:(CGFloat)backgroundCircleSize callback:(RCTResponseSenderBlock) callback;
@end
//in your m file
@implementation CMIconManager
+ (void)getImageForIcon:(UIImage*)icon fontSize:(CGFloat)fontSize fontColor:(UIColor *)fontColor imageWidth:(CGFloat)imageWidth imageHeight:(CGFloat)imageHeight backgroundCircleColor:(UIColor *)backgroundCircleColor backgroundCircleSize:(CGFloat)backgroundCircleSize callback:(RCTResponseSenderBlock) callback
{
//your implementation
}
@end
//call the method
[CMIconManager getImageForIcon:icon fontSize:size fontColor:color imageWidth:width imageHeight:height backgroundCircleColor:backgroundColor backgroundCircleSize:circleSize callback:callback];
在我看来,
getImageForIcon
是实例方法,但您使用的是类方法。这是非常可能的。我对Objective C完全陌生,我可能更喜欢使用JavaScript。在Objective C中会有什么不同?将“-(UIImage*)”更改为“+(UIImage*)”,但是没有有效的方法将数据从类方法发送到实例。我改用了“NSNotificatio”。更新了代码,仍然不起作用,但我认为这就是如何使用实例方法,对吗?谢谢@Artal,我已经阅读了关于本机模块的文档,但我对客观C缺乏了解。不过,我理解你在这里提出的前两点。所以我对代码进行了修改。上面列出的函数是另一个类中的函数,我希望在JS端重用并调用它。如何在回调中的这个新类中调用此方法?通过更新的代码,我看到错误“称为对象类型‘CMIconManager*’不是函数或函数指针。”以及“初始值设定项元素不是编译时常量”。您无法在代码中创建浮动对象的实例,这就是为什么出现错误初始值设定项元素不是编译时常量的原因。此外,您试图将此实例用作对方法的调用,即使如此-这不是在Objective C中调用实例方法的语法。您需要将代码放入RCT\u EXPORT\u方法
,或者您可以将getImageForIcon
转换为类方法,以便静态调用它。@Turnipdabeets我编辑了我的答案,以提供一个如何静态调用方法的示例。您应该知道,由于无法通过网桥传递UIImage
对象,因此将遇到其他问题,只允许序列化类型。您需要将它保存到一个文件并提供一个URL,或者您可以查看其他RN类如何在内部执行此操作,我认为他们有某种帮助类来处理它。谢谢@Artal。这是一个棕地应用程序,我正在尝试重用应用程序RN部分中已经实现的图标管理器。所以,我担心的是,如果我将getImageForIcon从一个实例方法更改为一个类方法,那么这不会导致以前使用此方法的应用程序本身出现其他问题吗?这是否意味着我别无选择,只能使用一种不那么枯燥的方法,将整个实例方法复制并粘贴到RCT_EXPORT_方法中?由于此函数返回UIImage,看起来我可能必须使用requireNativeComponent和RCT_EXPORT_VIEW_属性,对吗?因为您的方法不访问任何实例方法或属性,所以很容易将其转换为静态,然后在应用程序的其余部分更改方法调用(别担心,如果你遗漏了什么,编译器会告诉你的)。关于图像-它与视图属性无关,它和我写的差不多,可能是一个完全不同的问题的主题。。