Skip to content

Commit

Permalink
Merge pull request #36 from marco-mumtak/support-images
Browse files Browse the repository at this point in the history
Add support for images
  • Loading branch information
killserver authored Mar 14, 2024
2 parents 65255ce + 7f8f8fb commit 243590b
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 8 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# react-native-screenshot-prevent

### This fork contains fully working blank screenshot on IOS13+ including screen recording
### This fork contains fully working image screenshot cover on IOS13+ including screen recording
### App layout is white / or black in dark theme

#### For now you might disable RNPreventScreenshot.enableSecureView() in development mode (check __DEV__ variable)
Expand Down Expand Up @@ -63,6 +64,12 @@ RNPreventScreenshot.enabled(true/false);
*/
if(!__DEV__) RNPreventScreenshot.enableSecureView();

/* (IOS) enableSecureView for IOS13+
* creates a hidden secureTextField which prevents Application UI capture on screenshots
* and uses imgUri as the source of the background image (can be both https://, file:///)
*/
if(!__DEV__) RNPreventScreenshot.enableSecureView(imgUri);

/* (IOS) disableSecureView for IOS13+
* remove a hidden secureTextField which prevents Application UI capture on screenshots
*/
Expand Down
57 changes: 53 additions & 4 deletions ios/RNScreenshotPrevent.m
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

#import "RNScreenshotPrevent.h"
#import "UIImage+ImageEffects.h"

Expand Down Expand Up @@ -94,19 +93,69 @@ +(BOOL) requiresMainQueueSetup
return YES;
}

CGSize CGSizeAspectFit(const CGSize aspectRatio, const CGSize boundingSize)
{
CGSize aspectFitSize = CGSizeMake(boundingSize.width, boundingSize.height);
float mW = boundingSize.width / aspectRatio.width;
float mH = boundingSize.height / aspectRatio.height;
if( mH < mW )
aspectFitSize.width = mH * aspectRatio.width;
else if( mW < mH )
aspectFitSize.height = mW * aspectRatio.height;
return aspectFitSize;
}

CGSize CGSizeAspectFill(const CGSize aspectRatio, const CGSize minimumSize)
{
CGSize aspectFillSize = CGSizeMake(minimumSize.width, minimumSize.height);
float mW = minimumSize.width / aspectRatio.width;
float mH = minimumSize.height / aspectRatio.height;
if( mH > mW )
aspectFillSize.width = mH * aspectRatio.width;
else if( mW > mH )
aspectFillSize.height = mW * aspectRatio.height;
return aspectFillSize;
}


/**
* creates secure text field inside rootView of the app
* taken from https://stackoverflow.com/questions/18680028/prevent-screen-capture-in-an-ios-app
*
* converted to ObjC and modified to get it working with RCT
*/
-(void) addSecureTextFieldToView:(UIView *) view {
-(void) addSecureTextFieldToView:(UIView *) view :(NSString *) imagePath {

UIView *rootView = [UIApplication sharedApplication].keyWindow.rootViewController.view;


// fixes safe-area
secureField = [[UITextField alloc] initWithFrame:rootView.frame];
secureField.secureTextEntry = TRUE;
secureField.userInteractionEnabled = FALSE;

if (imagePath && ![imagePath isEqualToString:@""]) {
UIView * imgView = [[UIView alloc] initWithFrame:CGRectMake(0.f, 0.f, rootView.frame.size.width, rootView.frame.size.height)];
NSURL *url = [NSURL URLWithString:imagePath];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *img = [[UIImage alloc] initWithData:data];

CGSize sizeBeingScaledTo = CGSizeAspectFill(img.size, imgView.frame.size);

// redraw the image to fit the screen size
UIGraphicsBeginImageContextWithOptions(imgView.frame.size, NO, 0.f);

float offsetX = (imgView.frame.size.width - sizeBeingScaledTo.width) / 2;
float offsety = (imgView.frame.size.height - sizeBeingScaledTo.height) / 2;


[img drawInRect:CGRectMake(offsetX, offsety, sizeBeingScaledTo.width, sizeBeingScaledTo.height)];
UIImage * resultImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

secureField.backgroundColor = [UIColor colorWithPatternImage:resultImage];
}

[view sendSubviewToBack:secureField];
[view addSubview:secureField];
[view.layer.superlayer addSublayer:secureField.layer];
Expand All @@ -133,11 +182,11 @@ -(void) removeSecureTextFieldFromView:(UIView *) view {
}

/** adds secure textfield view */
RCT_EXPORT_METHOD(enableSecureView){
RCT_EXPORT_METHOD(enableSecureView: (NSString *)imagePath) {
if(secureField.secureTextEntry == false) {
UIView *view = [UIApplication sharedApplication].keyWindow.rootViewController.view;
for(UIView *subview in view.subviews) {
[self addSecureTextFieldToView:subview];
[self addSecureTextFieldToView:subview :imagePath];
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
declare module 'react-native-screenshot-prevent' {
export function enabled(value: boolean): void
export function enableSecureView(): void;
export function enableSecureView(imagePath?: string): void;
export function disableSecureView(): void;
export function usePreventScreenshot(): void;
export function useDisableSecureView(): void;
Expand Down
10 changes: 7 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,15 @@ type FN = (resp: any) => void
type Return = {
readonly remove: () => void
}

let addListen: any, RNScreenshotPrevent: any;
if(Platform.OS !== "web") {
const { RNScreenshotPrevent: RNScreenshotPreventNative } = NativeModules;
RNScreenshotPrevent = RNScreenshotPreventNative
RNScreenshotPrevent = {
...RNScreenshotPreventNative,
enableSecureView: function enableSecureView(imagePath = "") {
RNScreenshotPreventNative.enableSecureView(imagePath)
}
}
const eventEmitter = new NativeEventEmitter(RNScreenshotPrevent);

/**
Expand Down Expand Up @@ -78,7 +82,7 @@ export const useDisableSecureView = () => {
}

export const enabled: (enabled: boolean) => void = RNScreenshotPrevent.enabled
export const enableSecureView: () => void = RNScreenshotPrevent.enableSecureView
export const enableSecureView: (imagePath?: string) => void = RNScreenshotPrevent.enableSecureView
export const disableSecureView: () => void = RNScreenshotPrevent.disableSecureView
export const addListener: (fn: FN) => void = addListen
export default RNScreenshotPrevent;

0 comments on commit 243590b

Please sign in to comment.