我有一个银行应用程序,该应用程序要求禁用屏幕记录,并且我不希望人们使用新的iOS-11功能来记录带有敏感数据的屏幕并将其公开。由于无法在iOS中禁用屏幕录制,因此我尝试通过检测iOS11屏幕录制功能“开”或“关”来解决此问题。我使用了isCaptured和UIScreenCapturedDidChange Notification。代码如下:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
if (@available(iOS 11.0, *)) {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(screenCaptureChanged) name:UIScreenCapturedDidChangeNotification object:nil];
}
return YES;
}
-(void)screenCaptureChanged{
if (@available(iOS 11.0, *)) {
BOOL isCaptured = [[UIScreen mainScreen] isCaptured];// will keep on checking for screen recorder if it is runnuning or not.
if(isCaptured){
UIView *colourView = [[UIView alloc]initWithFrame:self.window.frame];
colourView.backgroundColor = [UIColor blackColor];
colourView.tag = 1234;
colourView.alpha = 0;
[self.window makeKeyAndVisible];
[self.window addSubview:colourView];
// fade in the view
[UIView animateWithDuration:0.5 animations:^{
colourView.alpha = 1;
}];
}else{
// grab a reference to our coloured view
UIView *colourView = [self.window viewWithTag:1234];
// fade away colour view from main view
[UIView animateWithDuration:0.5 animations:^{
colourView.alpha = 0;
} completion:^(BOOL finished) {
// remove when finished fading
[colourView removeFromSuperview];
}];
}
} else {
// Fallback on earlier versions
// grab a reference to our coloured view
UIView *colourView = [self.window viewWithTag:1234];
if(colourView!=nil){
// fade away colour view from main view
[UIView animateWithDuration:0.5 animations:^{
colourView.alpha = 0;
} completion:^(BOOL finished) {
// remove when finished fading
[colourView removeFromSuperview];
}];
}
}
}
因此,逻辑是在屏幕录制开始时触发通知,在录制发生时以及录制停止时在视频上放置黑色的逻辑被删除。当应用程序移至后台,活动,非活动和前景方案时,这可以很好地工作。但是,当应用程序被杀死(终止)而屏幕录制仍在进行时,而当我们再次启动应用程序而屏幕录制仍在进行时,黑色则无法覆盖屏幕。因此,如何在选择器方法正常工作的情况下再次调用通知选择器
答案 0 :(得分:1)
在isCaptured
中检查屏幕的application:didFinishLaunchingWithOptions:
属性的值,并相应地显示或隐藏覆盖视图。
UIWindow + ScreenCapture.h:
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface UIWindow (ScreenCapture)
- (void)showOrHideContentDependingOnCapturedState;
- (void)hideContent;
- (void)showContent;
@end
NS_ASSUME_NONNULL_END
UIWindow + ScreenCapture.m:
#import "UIWindow+ScreenCapture.h"
@implementation UIWindow (ScreenCapture)
- (void)showOrHideContentDependingOnCapturedState {
if (self.screen.isCaptured) {
[self hideContent];
} else {
[self showContent];
}
}
- (void)hideContent {
UIView *blackView = [self viewWithTag:1234];
if (!blackView) {
blackView = [[UIView alloc] initWithFrame:self.bounds];
}
blackView.tag = 1234;
blackView.backgroundColor = UIColor.blackColor;
blackView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
// This is important! If this is not set, then any new view added to
// the window (like the root view controller's view) will be overtop of
// `blackView`, which we don't want.
blackView.layer.zPosition = 10000;
[self addSubview:blackView];
}
- (void)showContent {
[[self viewWithTag:1234] removeFromSuperview];
}
@end
AppDelegate.h:
#import <UIKit/UIKit.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (nullable, strong, nonatomic) UIWindow *window;
@end
AppDelegate.m:
#import "AppDelegate.h"
#import "UIWindow+ScreenCapture.h"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(checkIsBeingRecorded)
name:UIScreenCapturedDidChangeNotification
object:nil];
[self.window showOrHideContentDependingOnCapturedState];
return YES;
}
- (void)checkIsBeingRecorded {
for (UIWindow *window in UIApplication.sharedApplication.windows) {
[window showOrHideContentDependingOnCapturedState];
}
}
@end