DylanVann / react-native-fast-image

🚩 FastImage, performant React Native image component.
MIT License
8.09k stars 1.47k forks source link

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

Open dprajapati1179 opened 9 months ago

dprajapati1179 commented 9 months ago

Hi! 👋

Firstly, thanks for your work on this project! 🙂

Today I used patch-package to patch react-native-fast-image@8.6.3 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 {
abakers commented 9 months ago

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

tkyr-hh commented 8 months ago

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

mzbyszynski commented 8 months ago

FYI Pr is #1012

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

dtyrrell commented 7 months ago

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.

Pratik-27 commented 2 months ago

Hi! 👋

Firstly, thanks for your work on this project! 🙂

Today I used patch-package to patch react-native-fast-image@8.6.3 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:

nes123 commented 3 weeks ago

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?