Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios React Native Bridge-在Objective-C中导出另一个文件中的一个函数_Ios_Objective C_React Native_React Native Ios - Fatal编程技术网

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
}
几个注意事项:

  • 在方法中不能只使用任何类型。您只能使用RN知道如何转换的类型,因此不能使用
    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_属性,对吗?因为您的方法不访问任何实例方法或属性,所以很容易将其转换为静态,然后在应用程序的其余部分更改方法调用(别担心,如果你遗漏了什么,编译器会告诉你的)。关于图像-它与视图属性无关,它和我写的差不多,可能是一个完全不同的问题的主题。。