Điều khiển ảnh chụp màn hình trong trình chuyển đổi đa nhiệm iOS 7


98

Tôi đang cố gắng tìm một số thông tin liên quan đến trình chuyển đổi đa nhiệm mới trong iOS 7 và đặc biệt là ảnh chụp màn hình mà hệ điều hành chụp khi ứng dụng chuyển sang chế độ ngủ đông.

nhập mô tả hình ảnh ở đây

Có cách nào để tắt hoàn toàn tính năng hoặc ảnh chụp màn hình này không? Hay tôi có thể ẩn ứng dụng hoàn toàn khỏi trình chuyển đổi không? Ứng dụng cần chạy ở chế độ nền, nhưng chúng tôi không muốn hiển thị bất kỳ ảnh chụp màn hình nào từ ứng dụng.

Ảnh chụp màn hình có khả năng gây rủi ro bảo mật, hãy suy nghĩ kỹ về ứng dụng ngân hàng, nơi số thẻ hoặc tóm tắt tài khoản của bạn sẽ khả dụng cho bất kỳ ai nhấp đúp vào nút trang chủ trên thiết bị.

Bất cứ ai có bất kỳ cái nhìn sâu sắc về điều này? Cảm ơn.


1
Giải pháp hiện tại của tôi là tải chế độ xem trống với logo ứng dụng khi ứng dụng chuyển sang chế độ ngủ đông và xóa nó khi ứng dụng quay trở lại, nhưng giải pháp đó khó quản lý và có vẻ giống như một vụ hack hơn là một giải pháp thanh lịch. Ngoài ra, giải pháp này thỉnh thoảng bị lỗi tùy thuộc vào thiết bị, v.v. Vì vậy, nó không thực sự là một giải pháp có thể sử dụng được.
Tommie

Câu trả lời:


101

Khi Chuẩn bị giao diện người dùng của bạn để chạy trong nền , Apple cho biết:

Chuẩn bị giao diện người dùng của bạn cho Ảnh chụp nhanh ứng dụng

Tại một số thời điểm sau khi ứng dụng của bạn vào nền và phương thức ủy quyền của bạn trở lại, UIKit sẽ chụp nhanh giao diện người dùng hiện tại của ứng dụng của bạn. Hệ thống hiển thị hình ảnh kết quả trong trình chuyển đổi ứng dụng. Nó cũng hiển thị hình ảnh tạm thời khi đưa ứng dụng của bạn trở lại nền trước.

Giao diện người dùng của ứng dụng của bạn không được chứa bất kỳ thông tin người dùng nhạy cảm nào, chẳng hạn như mật khẩu hoặc số thẻ tín dụng. Nếu giao diện của bạn chứa thông tin như vậy, hãy xóa thông tin đó khỏi chế độ xem của bạn khi nhập nền. Ngoài ra, loại bỏ cảnh báo, giao diện tạm thời và bộ điều khiển chế độ xem hệ thống che khuất nội dung ứng dụng của bạn. Ảnh chụp nhanh đại diện cho giao diện ứng dụng của bạn và người dùng phải dễ nhận biết. Khi ứng dụng của bạn trở lại nền trước, bạn có thể khôi phục dữ liệu và chế độ xem nếu thích hợp.

Xem phần hỏi đáp kỹ thuật QA1838: Ngăn thông tin nhạy cảm xuất hiện trong công cụ chuyển đổi tác vụ

Ngoài việc che khuất / thay thế thông tin nhạy cảm, bạn cũng có thể yêu cầu iOS 7 không chụp ảnh nhanh màn hình ignoreSnapshotOnNextApplicationLaunch, tài liệu có ghi:

Nếu bạn cảm thấy rằng ảnh chụp nhanh không thể phản ánh chính xác giao diện người dùng của ứng dụng khi ứng dụng của bạn được khởi chạy lại, bạn có thể gọi ignoreSnapshotOnNextApplicationLaunchđể ngăn không cho chụp ảnh chụp nhanh đó.

Có nói rằng, có vẻ như ảnh chụp nhanh màn hình vẫn được chụp và do đó tôi đã gửi báo cáo lỗi. Nhưng bạn nên kiểm tra thêm và xem việc sử dụng cài đặt này có hữu ích không.

Nếu đây là ứng dụng dành cho doanh nghiệp, bạn cũng có thể muốn xem xét cài đặt thích hợp được allowScreenShotnêu trong phần Tải trọng hạn chế của Tham chiếu hồ sơ cấu hình.


Đây là cách triển khai đạt được những gì tôi cần. Bạn có thể trình bày của riêng bạn UIImageViewhoặc của bạn có thể sử dụng một mẫu giao thức ủy quyền để che khuất thông tin bí mật:

//  SecureDelegate.h

#import <Foundation/Foundation.h>

@protocol SecureDelegate <NSObject>

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

@end

Sau đó, tôi đã cấp cho người ủy quyền ứng dụng của mình một thuộc tính cho điều đó:

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

Bộ điều khiển chế độ xem của tôi đặt nó:

- (void)viewDidLoad
{
    [super viewDidLoad];

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

Bộ điều khiển chế độ xem rõ ràng thực hiện giao thức đó:

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

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

Và, cuối cùng, đại biểu ứng dụng của tôi sử dụng chính giao thức và thuộc tính này:

- (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:"];
}

Lưu ý, tôi đang sử dụng applicationWillResignActivechứ không phải lời khuyên applicationDidEnterBackground, bởi vì, như những người khác đã chỉ ra, cái sau không được gọi khi nhấn đúp vào nút trang chủ trong khi ứng dụng đang chạy.

Tôi ước mình có thể sử dụng thông báo để xử lý tất cả những điều này, thay vì mẫu giao thức ủy quyền, nhưng trong thử nghiệm giới hạn của tôi, các thông báo không được xử lý kịp thời, nhưng mẫu trên hoạt động tốt.


6
Lưu ý rằng, như đã đề cập ở đây stackoverflow.com/questions/18937313/… , hành vi trong trình mô phỏng không phải lúc nào cũng giống như trên thiết bị!
Michael Forrest

5
Đối với giá trị của nó, ignoreSnapshotOnNextApplicationLaunchphương thức sẽ bị bỏ qua nếu nó không được gọi trong quá trình khôi phục trạng thái, như được mô tả ở đây .
Charles A.

3
Bạn không cần phải làm điều đó trong applicationWillResignActive vì ảnh chụp màn hình không được chụp cho đến khi applicationDidEnterBackground. Khi bạn nhấn đúp vào nút trang chủ, không có ảnh chụp màn hình nào được chụp; màn hình bạn đang xem đang hoạt động. Thêm hoạt ảnh vào màn hình của bạn để xác minh, ví dụ: màu nền chu kỳ. Nếu sau đó bạn chọn một ứng dụng khác, ứng dụngDidEnterBackground của bạn sẽ được gọi trước khi ảnh chụp màn hình thực tế được chụp.
honus

3
BTW, tôi đã được một kỹ sư của Apple thông báo rằng tài liệu đó ignoreSnapshotOnNextApplicationLaunchkhông chính xác, như tất cả chúng ta đều quan sát thấy, một bức ảnh chụp nhanh thực sự đã được chụp, nhưng đơn giản là sẽ không được sử dụng vào lần ra mắt tiếp theo.
Rob

2
ignoreSnapshotOnNextApplicationLaunch dường như làm những gì nó giống như: ngăn ảnh chụp màn hình hiển thị trong khi khởi chạy ứng dụng . Nó không ảnh hưởng đến ảnh chụp màn hình giao diện người dùng đa nhiệm hoặc nếu ứng dụng của bạn đang được tiếp tục thay vì khởi chạy.
Glenn Maynard

32

Đây là giải pháp tôi đã làm việc với ứng dụng của mình:

Như Tommy đã nói: Bạn có thể sử dụng ứng dụngWillResignActive. Những gì tôi đã làm là tạo một UIImageView với SplashImage của mình và thêm nó làm chế độ xem phụ vào cửa sổ chính của tôi-

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

Tôi đã sử dụng phương pháp này thay vì applicationDidEnterBackground vì applicationDidEnterBackground sẽ không được kích hoạt nếu bạn nhấn đúp vào nút trang chủ và applicationWillResignActive sẽ như vậy. Tôi nghe mọi người nói mặc dù nó có thể được kích hoạt trong các trường hợp khác, vì vậy tôi vẫn đang kiểm tra xung quanh để xem liệu nó có gây ra sự cố hay không, nhưng cho đến nay vẫn chưa có! ;)

Tại đây để xóa chế độ xem hình ảnh:

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

Hi vọng điêu nay co ich!

Sidenote: Tôi đã thử nghiệm điều này trên cả thiết bị giả lập và thiết bị thực: Nó sẽ không hiển thị trên trình mô phỏng, nhưng nó có trên thiết bị thực!


2
Có một nhược điểm: ứng dụngWillResignActive được gọi, trong số các trường hợp khác, khi người dùng kéo thanh thông báo xuống. Vì vậy, bạn trượt ngón tay từ trên xuống và xem hình ảnh đó, trong khi bạn đã mong đợi xem nội dung ứng dụng.
Kirill Gamazkov

4
Tốt hơn là làm mờ thông tin nhạy cảm trên ứng dụngWillResignActive và đặt imageView trên aplicationDidEnterBackground
Kirill Gamazkov

Điều này hoạt động, nhưng có một lỗi xoay khi được triển khai lên iOS7, được xây dựng bằng xCode6: stackoverflow.com/questions/26147068/…
Alex Stone

Nếu tôi viết mã mà bạn đã đề cập trong applicationWillResignActive , thì tôi sẽ thấy gì khi đưa Ứng dụng của mình trở lại trạng thái nền? Tôi sẽ thấy hình ảnh "Chân dung (768x1024) .png" hay màn hình thực tế?
NSPratik

2
@Pratik: Bạn sẽ thấy hình ảnh, trừ khi bạn xóa nó một lần nữa trong phương thức applicationDidBecomeActive (xem ở trên).
Laura

14

Phương pháp nhanh chóng và dễ dàng này sẽ mang lại ảnh chụp nhanh màu đen phía trên biểu tượng ứng dụng của bạn trong trình chuyển đổi ứng dụng iOS7 trở lên.

Đầu tiên, lấy cửa sổ khóa của ứng dụng của bạn (thường được thiết lập trong AppDelegate.m trong ứng dụng: didFinishLaunchingWithOptions) và ẩn nó khi ứng dụng của bạn sắp chuyển sang chế độ nền:

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

Sau đó, hãy bỏ ẩn cửa sổ khóa của ứng dụng khi ứng dụng của bạn hoạt động trở lại:

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

Tại thời điểm này, hãy kiểm tra trình chuyển đổi ứng dụng và xác minh rằng bạn nhìn thấy ảnh chụp nhanh màu đen phía trên biểu tượng ứng dụng của mình. Tôi nhận thấy rằng nếu bạn khởi chạy trình chuyển đổi ứng dụng ngay lập tức sau khi chuyển ứng dụng của bạn vào nền, có thể có độ trễ ~ 5 giây, nơi bạn sẽ thấy ảnh chụp nhanh của ứng dụng của mình (ảnh bạn muốn ẩn!), Sau mà nó chuyển sang ảnh chụp nhanh toàn màu đen. Tôi không chắc có chuyện gì với sự chậm trễ; nếu ai có bất kỳ đề nghị, xin vui lòng gọi trong.

Nếu bạn muốn có một màu khác ngoài màu đen trong trình chuyển đổi, bạn có thể làm điều gì đó như sau bằng cách thêm một chế độ xem phụ với bất kỳ màu nền nào bạn muốn:

- (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];
    }
}

Sau đó, xóa chế độ xem phụ màu này khi ứng dụng của bạn hoạt động trở lại:

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

4

Tôi đã sử dụng giải pháp sau: khi ứng dụng sắp từ chức, tôi nhận ảnh chụp nhanh appWindow dưới dạng Chế độ xem và thêm ảnh mờ cho nó. Sau đó, tôi thêm chế độ xem này vào cửa sổ ứng dụng

làm như thế nào:

  1. trong appDelegate ngay trước khi triển khai thêm dòng:

    static const int kNVSBlurViewTag = 198490;//or wherever number you like
  2. thêm các phương pháp này:

    - (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. thực hiện triển khai appDelegate của bạn như sau:

    - (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];
    }

Tôi tạo ra các dự án Ví dụ trong SwiftObjective C . Cả hai dự án đều thực hiện các hành động sau trong:

-application: didResignActive - ảnh chụp nhanh được tạo, làm mờ và thêm vào cửa sổ ứng dụng

-Ứng dụng: willBecomeActive mờ chế độ xem đang bị xóa khỏi cửa sổ.

Cách sử dụng:

Obecitve C

  1. Thêm AppDelegate+NVSBlurAppScreentệp .h và .m vào dự án của bạn

  2. trong phương thức -applicationWillResignActive: của bạn, hãy thêm dòng sau:

    [self nvs_blurPresentedView];
  3. trong phương thức -applicationDidEnterBackground: của bạn, thêm dòng sau:

    [self nvs_unblurPresentedView];

Nhanh

  1. thêm tệp AppDelegateExtention.swift vào dự án của bạn

  2. trong ứng dụng của bạn chức năngWillResignActive thêm dòng sau:

    blurPresentedView()
  3. trong hàm applicationDidBecomeActive của bạn thêm dòng sau:

    unblurPresentedView()

2

nếu chỉ sử dụng [self.window addSubview:imageView];trong applicationWillResignActivechức năng, ImageView này sẽ không bao gồm UIAlertView, UIActionSheet hoặc MFMailComposeViewController ...

Giải pháp tốt nhất là

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

Giải pháp rất tốt nếu bạn có video đang phát ở chế độ toàn màn hình trong chế độ xem web!
Tommie

Thông minh!. Nó hoạt động ngay cả khi chúng ta mở bàn phím trước khi vào trình chuyển đổi đa nhiệm! Cảm ơn
Prabhu.Somasundaram

0

Cung cấp giải pháp của riêng tôi như một "câu trả lời", mặc dù giải pháp này rất không đáng tin cậy. Đôi khi tôi nhận được màn hình đen như ảnh chụp màn hình, đôi khi là XIB và đôi khi là ảnh chụp màn hình từ chính ứng dụng. Tùy thuộc vào thiết bị và / hoặc nếu tôi chạy điều này trong trình mô phỏng.

Xin lưu ý rằng tôi không thể cung cấp bất kỳ mã nào cho giải pháp này vì có rất nhiều chi tiết dành riêng cho ứng dụng trong đó. Nhưng điều này sẽ giải thích ý chính cơ bản của giải pháp của tôi.

Trong AppDelegate.m dưới ứng dụng applicationWillResignActive, tôi kiểm tra xem chúng tôi có đang chạy iOS7 hay không, nếu chúng tôi tải một chế độ xem mới trống với logo ứng dụng ở giữa. Khi ứng dụngDidBecomeActive được gọi, tôi khởi chạy lại các chế độ xem cũ của mình, chế độ này sẽ được đặt lại - nhưng điều đó hoạt động đối với loại ứng dụng mà tôi đang phát triển.


1
Nếu bạn thấy những gì các ứng dụng máy ảnh không - nó chuyển hình ảnh vào một mờ khi đi vào nền (bạn có thể thấy sự chuyển đổi vì nó làm giảm biểu tượng)
Petesh

@Petesh Vâng, đó là một cách triển khai tốt, nhưng câu hỏi là họ thực hiện nó như thế nào. Tôi sợ một API riêng.
Rob

@Tommie Bạn nói "Tùy thuộc vào thiết bị và / hoặc nếu tôi chạy điều này trong trình mô phỏng". Đối với tôi, nó dường như hoạt động trên thiết bị (mặc dù tôi chưa thực hiện kiểm tra toàn diện), nhưng không hoạt động trên trình mô phỏng. Bạn có thấy nó không hoạt động trên thiết bị không?
Rob

0

Bạn có thể sử dụng trình kích hoạt để định cấu hình nhấp đúp vào nút trang chủ để khởi chạy đa nhiệm và tắt nhấp đúp mặc định vào nút trang chủ và khởi chạy cửa sổ đa nhiệm. Phương pháp này có thể được sử dụng để thay đổi ảnh chụp màn hình thành hình ảnh mặc định của ứng dụng. Điều này có thể áp dụng cho các ứng dụng có tính năng bảo vệ bằng mật mã mặc định.


-2

Xamarin.iOS

Phỏng theo https://stackoverflow.com/a/20040270/7561

Thay vì chỉ hiển thị một màu, tôi muốn hiển thị màn hình khởi chạy của mình.

 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();
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.