2017-04-21 38 views
0

CMIconManager.m我有一個叫做getImageForIcon的函數。React Native Bridge - 在Objective-C中導出另一個文件中的一個函數

- (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; 
} 

我如何通過此功能RCT_EXPORT_METHOD()在新文件:RNIconManager.m

#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)]); 
} 
+0

這在我看來,'getImageForIcon'是實例方法,但你使用這個像類方法。 – Ryan

+0

這很可能。我對Objective C完全陌生,我可能更像JavaScript一樣使用它。目標C中的差異是什麼? – Turnipdabeets

+0

將' - (UIImage *)'更改爲'+(UIImage *)',但沒有有效的方法將數據從類方法發送到實例。我用'NSNotificatio'代替。 – Ryan

回答

0

RCT_EXPORT_METHOD宏接受整個方法簽名作爲參數,所以它看起來是這樣的:

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 
} 

有兩點要注意:

  1. 你可以用」只是在你的方法中使用任何類型。您只能使用RN知道如何轉換的類型,因此您不能使用CMIcon
  2. 您不能簡單地從導出的方法返回值。如果您需要返回某些內容,則需要傳遞迴調或使用承諾。
  3. 如果您希望調用的實際函數是在另一個類中找到的,那麼您仍然需要按照前面所述執行導出操作,但在此導出的方法中,您可以調用另一個方法 - 它可以是靜態方法或實例方法根據你的代碼的寫法。

你真的應該看看Native Modules的文檔,它有你需要的所有信息和例子。

編輯: 這裏是你如何能暴露一個類的方法,你可以靜態調用的例子:

//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]; 
+0

謝謝@Artal,我已經閱讀了原生模塊的文檔,但我缺乏Objective C的理解。不過,我瞭解你在這裏提出的前兩點。所以我在我的代碼中進行了更改。上面列出的函數是另一個類中的函數,我希望重用和調用JS端。如何在回調中的這個新類中調用此方法?使用更新後的代碼,我看到錯誤「調用的對象類型'CMIconManager *'不是函數或函數指針。」和「初始化元素不是編譯時常量」。 – Turnipdabeets

+0

您不能在代碼中創建浮動對象的實例,這就是爲什麼您會收到錯誤'初始化元素不是編譯時常量'。另外,您試圖將此實例用作對方法的調用,即使如此 - 這不是在Objective C中調用實例方法的語法。您需要將代碼放入'RCT_EXPORT_METHOD'中,否則可以將'getImageForIcon'變成一個類方法,所以你可以靜態調用它。 – Artal

+0

@Turnipdabeets我編輯了我的答案,以提供如何靜態調用您的方法的示例。你應該知道你會遇到更多的問題,因爲無法在橋上傳遞'UIImage'對象,所以只能使用可序列化的類型。你需要將它保存到一個文件並提供一個URL,或者你可以看看其他RN類在內部如何做,我認爲他們有一些幫助類來處理它。 – Artal

相關問題