2013-09-23 97 views
90

我一直在嘗試查找有關iOS 7中新多任務切換器的一些信息,尤其是應用程序進入休眠狀態時操作系統採用的屏幕截圖。在iOS 7多任務切換器中控制屏幕截圖

enter image description here

有沒有辦法徹底關閉這個功能或者截圖?或者我可以從切換臺完全隱藏應用程序嗎?該應用程序需要在後臺運行,但我們不想顯示應用程序的任何屏幕截圖。

該屏幕截圖可能存在安全風險,請考慮銀行應用程序的行爲,其中您的卡號或帳戶摘要可供雙擊設備上主頁按鈕的任何人使用。

任何有洞察力的人?謝謝。

+1

我目前的解決方案是,一旦應用程序進入休眠狀態加載空白視圖與應用程序標識和刪除應用程序返回時,但這種解決方案難以管理和似乎是一個黑客,而不是優雅的解決方案。 此外,此解決方案不時取決於設備等,所以它不是一個真正可用的。 – Tommie

+0

@Rob - 當然,我會很快提供我的解決方案作爲「答案」,最壞的情況是,這實際上是解決這個問題的方法。 – Tommie

回答

89

App Programming Guide for iOS,蘋果說:

移動到後臺之前,從視圖中除去敏感信息。

當應用程序轉換到後臺時,系統會拍攝應用程序主窗口的快照,然後在將應用程序轉換回前臺時,該窗口會短暫顯示。在從applicationDidEnterBackground:方法返回之前,您應該隱藏或遮掩可能作爲快照一部分捕獲的密碼和其他敏感個人信息。

除了隱藏/替換敏感信息之外,您可能還想告訴iOS 7不要通過ignoreSnapshotOnNextApplicationLaunch拍攝屏幕快照。根據the documentation此方法:

如果你覺得快照不能正確反映你的應用程序的用戶界面時,您的應用程序重新啓動,你可以調用[ignoreSnapshotOnNextApplicationLaunch]以防止採取快照圖像。

話雖如此,看起來屏幕快照仍然被採用,因此我提交了一個錯誤報告。但是你應該進一步測試,看看使用這個設置是否有幫助。

如果這是一個企業應用程序,您可能還需要查看配置文件參考的Restrictions Payload部分中概述的allowScreenShot的相應設置。


這是一個實現我所需要的實現。您可以將您自己的UIImageView,或者您可以使用一個委託協議模式掩蓋了機密信息:

// SecureDelegate.h 

#import <Foundation/Foundation.h> 

@protocol SecureDelegate <NSObject> 

- (void)hide:(id)object; 
- (void)show:(id)object; 

@end 

然後我給我的應用程序委託一個屬性:

@property (weak, nonatomic) id<SecureDelegate> secureDelegate; 

我的視圖控制器將其設置:

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    AppDelegate *delegate = [[UIApplication sharedApplication] delegate]; 
    delegate.secureDelegate = self; 
} 

視圖控制器顯然實現了協議:

- (void)hide:(id)object 
{ 
    self.passwordLabel.alpha = 0.0; 
} 

- (void)show:(id)object 
{ 
    self.passwordLabel.alpha = 1.0; 
} 

最後,我的應用程序委託援用該協議和財產本身:

- (void)applicationWillResignActive:(UIApplication *)application 
{ 
    [application ignoreSnapshotOnNextApplicationLaunch]; // this doesn't appear to work, whether called here or `didFinishLaunchingWithOptions`, but seems prudent to include it 

    [self.secureDelegate hide:@"applicationWillResignActive:"]; // you don't need to pass the "object", but it was useful during my testing... 
} 

- (void)applicationDidBecomeActive:(UIApplication *)application 
{ 
    [self.secureDelegate show:@"applicationDidBecomeActive:"]; 
} 

注意,我使用的是applicationWillResignActive而非勸applicationDidEnterBackground,因爲,正如其他人所指出的,後者在應用程序運行時雙擊主頁按鈕時不會調用。

我希望我可以使用通知來處理所有這些,而不是委託協議模式,但在我的有限測試中,通知不能及時處理,但上述模式工作正常。

+0

感謝您的解決方案Rob,您的document-digging-fu比我的要好:)不過,我們走了一條略有不同的路線,因爲我們從來沒有忽略ignoreSnapshotOnNextApplicationLaunch工作。它可能是關於你提交給蘋果公司的錯誤報告。您介意與我們分享您的示例代碼嗎?至少我們有什麼可比較的。再次感謝! – Tommie

+5

請注意,正如這裏提到http://stackoverflow.com/questions/18937313/unable-to-update-view-when-app-goes-into-background-in-ios-7-using-applicationdi行爲不是在模擬器上始終與設備上一樣! –

+0

@Rob您在'applicationDidEnterBackground'方法中隱藏了機密信息?但從前臺和用戶點擊主頁按鈕2x以及多任務顯示怎麼樣。我的應用程序還沒有進入背景,因此'applicationDidEnterBackground'&'applicationWillResignActive'不會被調用。 – HelmiB

0

提供我自己的解決方案作爲「答案」,儘管此解決方案非常不可靠。有時候我會在屏幕截圖上看到黑屏,有時候會出現XIB,有時還會出現應用本身的屏幕截圖。根據設備和/或如果我在模擬器中運行。

請注意我無法提供此解決方案的任何代碼,因爲它有很多特定於應用程序的細節。但是這應該解釋我的解決方案的基本要點。

在AppDelegate.m applicationWillResignActive下我檢查,如果我們 運行iOS7,如果現在我打開一個新視圖裏面是空的,在中間的 APP-標誌。一旦applicationDidBecomeActive被稱爲i 重新啓動我的舊視圖,這將被重置 - 但這適用於我正在開發的 類型的應用程序。

+1

如果您看到相機應用的功能 - 在進入背景時會將圖像轉換爲模糊圖像(您可以看到圖像變爲縮略圖) – Petesh

+0

@Petesh是的,這是一個很好的實現,但問題是他們是如何做到的。我擔心私人API。 – Rob

+0

@Tommie你說「根據設備和/或如果我在模擬器中運行」。對我來說,它似乎在設備上工作(雖然我沒有做過徹底的測試),但不是模擬器。你發現它不適用於設備? – Rob

31

這是我和我的應用程序工作的解決方案:

托米說:你可以使用applicationWillResignActive。我所做的就是做一個UIImageView與我SplashImage和它作爲子視圖添加到我的主窗口 -

(void)applicationWillResignActive:(UIApplication *)application 
{ 
    imageView = [[UIImageView alloc]initWithFrame:[self.window frame]]; 
    [imageView setImage:[UIImage imageNamed:@"Portrait(768x1024).png"]]; 
    [self.window addSubview:imageView]; 
} 

我用這個方法,而不是applicationDidEnterBackground因爲如果你doubletap home鍵applicationDidEnterBackground不會被觸發,applicationWillResignActive將會。我聽到人們說,雖然它也可以在其他情況下觸發,所以我仍在四處測試,看看它是否會產生問題,但目前還沒有。 ;)

這裏刪除的ImageView:

- (void)applicationDidBecomeActive:(UIApplication *)application 
{ 
    if(imageView != nil) { 
     [imageView removeFromSuperview]; 
     imageView = nil; 
    } 
} 

希望這有助於!

旁註:我在模擬器和真實設備上都測試過它:它不會在模擬器上顯示,但它會在真實設備上顯示!

+1

有一個缺點:applicationWillResignActive在其他情況下被調用,當用戶拉下通知碼頭時。因此,您可以從頂部向下滑動手指並看到該圖像,而您預計會看到應用內容。 –

+3

最好在applicationWillResignActive上模糊敏感信息,並在應用程序上設置imageViewDidEnterBackground –

+0

這可以工作,但是當部署到使用xCode6構建的iOS7時存在旋轉錯誤:http://stackoverflow.com/questions/26147068/xcode6-incorrect-view-控制器定位當部署到ios7設備 –

14

這種快速簡便的方法會在iOS7或更高版本的應用程序切換器中在應用程序圖標上方產生黑色快照。

首先,把你的應用程序的關鍵窗口(通常設置在AppDelegate中。米的application:didFinishLaunchingWithOptions),並把它隱藏在你的應用程序將要移動到背景:

- (void)applicationWillResignActive:(UIApplication *)application 
{ 
    if(isIOS7Or8) 
    { 
     self.window.hidden = YES; 
    } 
} 

然後,取消隱藏您的應用程序的重要窗口,當你的應用程序再次活躍變爲:

- (void)applicationDidBecomeActive:(UIApplication *)application 
{ 
    if(isIOS7Or8) 
    { 
     self.window.hidden = NO; 
    } 
} 

此時,請查看應用切換器並確認您在應用圖標上方看到黑色快照。我注意到,如果您在將應用移動到後臺後立即啓動應用切換器,則可能會延遲約5秒,您將在其中看到應用快照(您想要隱藏的應用),之後它轉換爲全黑快照。我不確定延遲會發生什麼;如果任何人有任何建議,請附和

如果你想比黑色在轉接器以外的顏色,你可以通過添加任何背景顏色子視圖做這樣的事情,你想:

- (void)applicationWillResignActive:(UIApplication *)application 
{ 
    if(isIOS7Or8) 
    { 
     UIView *colorView = [[[UIView alloc] initWithFrame:self.window.frame] autorelease]; 
     colorView.tag = 9999; 
     colorView.backgroundColor = [UIColor purpleColor]; 
     [self.window addSubview:colorView]; 
     [self.window bringSubviewToFront:colorView]; 
    } 
} 

然後,刪除這個顏色子視圖時,您的應用程序再次活躍變爲:

- (void)applicationDidBecomeActive:(UIApplication *)application 
{ 
    if(isIOS7Or8) 
    { 
     UIView *colorView = [self.window viewWithTag:9999]; 
     [colorView removeFromSuperview]; 
    } 
} 
+0

有什麼方法可以將黑色快照更改爲另一種純色? – SAHM

+0

@JPK - 我添加了一個如何做到這一點的例子。 –

0

您可以使用激活配置主頁按鈕的雙擊啓動多任務處理和禁用home鍵和多任務窗口啓動的默認雙擊。此方法可用於將屏幕截圖更改爲應用程序的默認圖像。這適用於具有默認密碼保護功能的應用程序。

1

如果只在applicationWillResignActive功能使用[self.window addSubview:imageView];,這ImageView的將不包括UIAlertView中,UIActionSheet或MFMailComposeViewController ...

最好的解決辦法是

- (void)applicationWillResignActive:(UIApplication *)application 
{ 
    UIWindow *mainWindow = [[[UIApplication sharedApplication] windows] lastObject]; 
    [mainWindow addSubview:imageView]; 
} 
+0

非常好的解決方案,如果你有一個視頻在全屏模式下在web視圖中播放! – Tommie

+0

優秀!即使我們在進入多任務切換器之前打開了鍵盤,它也能正常工作!謝謝 –

3

我用以下解決方案: 當應用程序要辭職我將appWindow快照視爲View併爲其添加模糊。然後我這個視圖添加到應用程序窗口

如何做到這一點:

  1. 中的appDelegate

    剛剛實施的附加前行:

    static const int kNVSBlurViewTag = 198490;//or wherever number you like 
    
  2. 添加這個方法:

    - (void)nvs_blurPresentedView 
        { 
         if ([self.window viewWithTag:kNVSBlurViewTag]){ 
          return; 
         } 
         [self.window addSubview:[self p_blurView]]; 
        } 
    
        - (void)nvs_unblurPresentedView 
        { 
         [[self.window viewWithTag:kNVSBlurViewTag] removeFromSuperview]; 
        } 
    
        #pragma mark - Private 
    
        - (UIView *)p_blurView 
        { 
         UIView *snapshot = [self.window snapshotViewAfterScreenUpdates:NO]; 
    
         UIView *blurView = nil; 
         if ([UIVisualEffectView class]){ 
          UIVisualEffectView *aView = [[UIVisualEffectView alloc]initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleDark]]; 
          blurView  = aView; 
          blurView.frame = snapshot.bounds; 
          [snapshot addSubview:aView]; 
         } 
         else { 
          UIToolbar *toolBar = [[UIToolbar alloc] initWithFrame:snapshot.bounds]; 
          toolBar.barStyle = UIBarStyleBlackTranslucent; 
          [snapshot addSubview:toolBar]; 
         } 
         snapshot.tag = kNVSBlurViewTag; 
         return snapshot; 
        } 
    
  3. 讓你的appDelegate實現如下:

    - (void)applicationWillResignActive:(UIApplication *)application { 
        // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 
        // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 
        //... 
        //your code 
        //... 
    
        [self nvs_blurPresentedView]; 
    } 
    
        - (void)applicationWillEnterForeground:(UIApplication *)application { 
        // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 
        //... 
        //your code 
        //... 
    
        [self nvs_unblurPresentedView]; 
    } 
    

我在SwiftObjective C創建實施例的項目。 兩個項目使得以下操作:

-application:didResignActive - 快照被創建,被弄髒並添加到應用程序窗口

-application:willBecomeActive模糊視圖被從窗口中移除。

如何使用:

ObjecitveÇ

  1. 添加AppDelegate+NVSBlurAppScreen h和.m文件到您的項目

  2. 在-applicationWillResignActive:方法添加下面一行:

    [self nvs_blurPresentedView]; 
    
  3. 在-applicationDidEnterBackground:方法中添加以下行:

    [self nvs_unblurPresentedView]; 
    

斯威夫特

  1. 在applicationWillResignActive功能AppDelegateExtention.swift文件添加到您的項目

  2. 添加以下行:

    blurPresentedView() 
    
  3. 在applicationDidBecomeActive功能

    添加以下行:

    unblurPresentedView() 
    
-1

Xamarin.iOS

https://stackoverflow.com/a/20040270/7561

而不是改編只是顯示一種顏色,我想展示我的啓動畫面。

public override void DidEnterBackground(UIApplication application) 
{ 
    //to add the background image in place of 'active' image 
    var backgroundImage = new UIImageView(); 
    backgroundImage.Tag = 1234; 
    backgroundImage.Image = UIImage.FromBundle("Background"); 
    backgroundImage.Frame = this.window.Frame; 
    this.window.AddSubview(backgroundImage); 
    this.window.BringSubviewToFront(backgroundImage); 
} 

public override void WillEnterForeground(UIApplication application) 
{ 
    //remove 'background' image 
    var backgroundView = this.window.ViewWithTag(1234); 
    if(null != backgroundView) 
     backgroundView.RemoveFromSuperview(); 
}