Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

4.0.0-alpha.3 ios snapshot wrong #539

Open
MmyzFlowerDog opened this issue Aug 1, 2024 · 0 comments
Open

4.0.0-alpha.3 ios snapshot wrong #539

MmyzFlowerDog opened this issue Aug 1, 2024 · 0 comments

Comments

@MmyzFlowerDog
Copy link

RCT_EXPORT_METHOD(captureRef:(nonnull NSNumber *)target
withOptions:(NSDictionary *)options
resolve:(RCTPromiseResolveBlock)resolve
reject:(RCTPromiseRejectBlock)reject)
{
[self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {

// Get view
UIView *view;

if ([target intValue] == -1) {
  UIWindow *window = [[UIApplication sharedApplication] keyWindow];
  view = window;
} else {
  view = viewRegistry[target];
}

if (!view) {
  reject(RCTErrorUnspecified, [NSString stringWithFormat:@"No view found with reactTag: %@", target], nil);
  return;
}

// Get options
CGSize size = [RCTConvert CGSize:options];
NSString *format = [RCTConvert NSString:options[@"format"]];
NSString *result = [RCTConvert NSString:options[@"result"]];
BOOL renderInContext = [RCTConvert BOOL:options[@"useRenderInContext"]];
BOOL snapshotContentContainer = [RCTConvert BOOL:options[@"snapshotContentContainer"]];

// Capture image
BOOL success;

UIView* rendered;
UIScrollView* scrollView;
if (snapshotContentContainer) {
  if (![view isKindOfClass:[RCTScrollView class]]) {
    reject(RCTErrorUnspecified, [NSString stringWithFormat:@"snapshotContentContainer can only be used on a RCTScrollView. instead got: %@", view], nil);
    return;
  }
  RCTScrollView* rctScrollView = view;
  scrollView = rctScrollView.scrollView;
  rendered = scrollView;
}
else {
  rendered = view;
}

if (size.width < 0.1 || size.height < 0.1) {
  size = snapshotContentContainer ? scrollView.contentSize : view.bounds.size;
}
if (size.width < 0.1 || size.height < 0.1) {
  reject(RCTErrorUnspecified, [NSString stringWithFormat:@"The content size must not be zero or negative. Got: (%g, %g)", size.width, size.height], nil);
  return;
}

CGPoint savedContentOffset;
CGRect savedFrame;
if (snapshotContentContainer) {
  // Save scroll & frame and set it temporarily to the full content size
  savedContentOffset = scrollView.contentOffset;
  savedFrame = scrollView.frame;
  scrollView.contentOffset = CGPointZero;
  scrollView.frame = CGRectMake(0, 0, scrollView.contentSize.width, scrollView.contentSize.height);
}

UIGraphicsImageRenderer *renderer = [[UIGraphicsImageRenderer alloc] initWithSize:size];

if (renderInContext) {
  // this comes with some trade-offs such as inability to capture gradients or scrollview's content in full but it works for large views
  [rendered.layer renderInContext: UIGraphicsGetCurrentContext()];
  success = YES;
}
else {
  // this doesn't work for large views and reports incorrect success even though the image is blank
  success = [rendered drawViewHierarchyInRect:(CGRect){CGPointZero, size} afterScreenUpdates:YES];
}
  

UIImage *image = [renderer imageWithActions:^(UIGraphicsImageRendererContext * _Nonnull rendererContext) {}];

if (snapshotContentContainer) {
  // Restore scroll & frame
  scrollView.contentOffset = savedContentOffset;
  scrollView.frame = savedFrame;
}


In this method, " UIImage *image = [renderer imageWithActions:^(UIGraphicsImageRendererContext * _Nonnull rendererContext) {}];"
should be " UIImage *image = [renderer imageWithActions:^(UIGraphicsImageRendererContext * _Nonnull rendererContext) {
[rendered.layer renderInContext:rendererContext.CGContext];
}];" ,
or it will make the image become empty white in IOS17,

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant