react-native-fast-image icon indicating copy to clipboard operation
react-native-fast-image copied to clipboard

Crashes the app, as IOS has deprecated UIGraphicsBeginImageContextWithOptions from IOS 17.

Open dprajapati1179 opened this issue 2 years ago • 7 comments

Hi! 👋

Firstly, thanks for your work on this project! 🙂

Today I used patch-package to patch [email protected] for the project I'm working on.

Getting crash on iOS 17 as UIGraphicsBeginImageContextWithOptions. It crashes the app, as IOS has deprecated UIGraphicsBeginImageContextWithOptions from IOS 17.

Here is the diff that solved my problem:

diff --git a/node_modules/react-native-fast-image/ios/FastImage/FFFastImageView.m b/node_modules/react-native-fast-image/ios/FastImage/FFFastImageView.m
index f710081..fe20770 100644
--- a/node_modules/react-native-fast-image/ios/FastImage/FFFastImageView.m
+++ b/node_modules/react-native-fast-image/ios/FastImage/FFFastImageView.m
@@ -73,12 +73,17 @@ - (void) setImageColor: (UIColor*)imageColor {
 
 - (UIImage*) makeImage: (UIImage*)image withTint: (UIColor*)color {
     UIImage* newImage = [image imageWithRenderingMode: UIImageRenderingModeAlwaysTemplate];
-    UIGraphicsBeginImageContextWithOptions(image.size, NO, newImage.scale);
-    [color set];
-    [newImage drawInRect: CGRectMake(0, 0, image.size.width, newImage.size.height)];
-    newImage = UIGraphicsGetImageFromCurrentImageContext();
-    UIGraphicsEndImageContext();
-    return newImage;
+    
+    UIGraphicsImageRendererFormat *format = [UIGraphicsImageRendererFormat defaultFormat];
+    UIGraphicsImageRenderer *renderer = [[UIGraphicsImageRenderer alloc] initWithSize:image.size format:format];
+
+    UIImage *resultImage = [renderer imageWithActions:^(UIGraphicsImageRendererContext * _Nonnull rendererContext) {
+        CGRect rect = CGRectMake(0, 0, image.size.width, image.size.height);
+        [color set];
+        [newImage drawInRect:rect];
+    }];
+
+    return resultImage;
 }
 
 - (void) setImage: (UIImage*)image {

dprajapati1179 avatar Oct 05 '23 07:10 dprajapati1179

Had the same issue, your solution solved it for us. Thank you!

abakers avatar Oct 06 '23 12:10 abakers

@dprajapati1179 I really appreciate sharing your solution, can you please open a PR with this Fix??

tkyr-hh avatar Oct 09 '23 09:10 tkyr-hh

FYI Pr is #1012

Note that the change in pr #1007 is also very similar and should fix this isssue.

mzbyszynski avatar Oct 23 '23 16:10 mzbyszynski

Do you have repro steps for this @dprajapati1179 ?

I'm running 8.6.3 and my app seems fine on iOS 17 & 17.1 based on the limited testing i've done.

dtyrrell avatar Nov 14 '23 11:11 dtyrrell

Hi! 👋

Firstly, thanks for your work on this project! 🙂

Today I used patch-package to patch [email protected] for the project I'm working on.

Getting crash on iOS 17 as UIGraphicsBeginImageContextWithOptions. It crashes the app, as IOS has deprecated UIGraphicsBeginImageContextWithOptions from IOS 17.

Here is the diff that solved my problem:

diff --git a/node_modules/react-native-fast-image/ios/FastImage/FFFastImageView.m b/node_modules/react-native-fast-image/ios/FastImage/FFFastImageView.m
index f710081..fe20770 100644
--- a/node_modules/react-native-fast-image/ios/FastImage/FFFastImageView.m
+++ b/node_modules/react-native-fast-image/ios/FastImage/FFFastImageView.m
@@ -73,12 +73,17 @@ - (void) setImageColor: (UIColor*)imageColor {
 
 - (UIImage*) makeImage: (UIImage*)image withTint: (UIColor*)color {
     UIImage* newImage = [image imageWithRenderingMode: UIImageRenderingModeAlwaysTemplate];
-    UIGraphicsBeginImageContextWithOptions(image.size, NO, newImage.scale);
-    [color set];
-    [newImage drawInRect: CGRectMake(0, 0, image.size.width, newImage.size.height)];
-    newImage = UIGraphicsGetImageFromCurrentImageContext();
-    UIGraphicsEndImageContext();
-    return newImage;
+    
+    UIGraphicsImageRendererFormat *format = [UIGraphicsImageRendererFormat defaultFormat];
+    UIGraphicsImageRenderer *renderer = [[UIGraphicsImageRenderer alloc] initWithSize:image.size format:format];
+
+    UIImage *resultImage = [renderer imageWithActions:^(UIGraphicsImageRendererContext * _Nonnull rendererContext) {
+        CGRect rect = CGRectMake(0, 0, image.size.width, image.size.height);
+        [color set];
+        [newImage drawInRect:rect];
+    }];
+
+    return resultImage;
 }
 
 - (void) setImage: (UIImage*)image {

Thanks for this solution but i found that tintColor prop does not work in this solution hence providing an alternative for the same:

  • (UIImage*)makeImage:(UIImage *)image withTint:(UIColor *)color { UIImage *newImage = [image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; UIGraphicsImageRendererFormat *format = [UIGraphicsImageRendererFormat defaultFormat]; UIGraphicsImageRenderer *renderer = [[UIGraphicsImageRenderer alloc] initWithSize:image.size format:format];

    UIImage *resultImage = [renderer imageWithActions:^(UIGraphicsImageRendererContext * _Nonnull rendererContext) { CGRect rect = CGRectMake(0, 0, image.size.width, image.size.height); [newImage drawInRect:rect]; CGContextRef context = rendererContext.CGContext; CGContextSetBlendMode(context, kCGBlendModeSourceAtop); [color setFill]; CGContextFillRect(context, rect); }];

    return resultImage; }

Pratik-27 avatar Apr 09 '24 08:04 Pratik-27

After implementing this patch there is a new error, "nan" in size rather then "0":

UIGraphicsBeginImageContext() failed to allocate CGBitampContext: size={nan, nan}, scale=1.000000, bitmapInfo=0x2002. Use UIGraphicsImageRenderer

any ideas what can cause that?

nes123 avatar Jun 13 '24 09:06 nes123

If you don't want changes in node_modules. Use this package (froked) - https://www.npmjs.com/package/@codegv/react-native-fast-image

codeGV avatar Jul 25 '24 11:07 codeGV