アプリ Snapchat は、App Storeで、写真を自己破壊して共有できるアプリです。写真はX秒間のみ表示できます。ホームパワーキーコンボを使用して写真が表示されているときにスクリーンショットを撮ろうとすると、スクリーンショットを撮ろうとしたことが送信者に通知されます。
ユーザーがスクリーンショットを撮影していることをSDKのどの部分で検出できますか?これが可能だとは知りませんでした。
答えが見つかりました!!スクリーンショットを撮ると、画面上のタッチが中断されます。これが、snapchatが写真を見るために保持する必要がある理由です。参考: http://tumblr.jeremyjohnstone.com/post/38503925370/how-to-detect-screenshots-on-ios-like-snapchat
IOS 7以降、他の答えは当てはまりません。 Appleが作成したため、ユーザーがスクリーンショットを撮ったときにtouchesCancelled:withEvent:
が呼び出されなくなりました。
これにより、Snapchatは事実上完全に破損するため、新しいソリューションにいくつかのベータ版が追加されました。これで、NSNotificationCenterを使用して IApplicationUserDidTakeScreenshotNotification にオブザーバーを追加するのと同じくらい簡単に解決できます。
次に例を示します。
NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];
[[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationUserDidTakeScreenshotNotification
object:nil
queue:mainQueue
usingBlock:^(NSNotification *note) {
// executes after screenshot
}];
NotificationCenter.default.addObserver(
forName: .UIApplicationUserDidTakeScreenshot,
object: nil,
queue: .main) { notification in
//executes after screenshot
}
Swiftでクロージャを使用する方法は次のとおりです。
func detectScreenShot(action: () -> ()) {
let mainQueue = NSOperationQueue.mainQueue()
NSNotificationCenter.defaultCenter().addObserverForName(UIApplicationUserDidTakeScreenshotNotification, object: nil, queue: mainQueue) { notification in
// executes after screenshot
action()
}
}
detectScreenShot { () -> () in
print("User took a screen shot")
}
Swift 4.2
func detectScreenShot(action: @escaping () -> ()) {
let mainQueue = OperationQueue.main
NotificationCenter.default.addObserver(forName: UIApplication.userDidTakeScreenshotNotification, object: nil, queue: mainQueue) { notification in
// executes after screenshot
action()
}
}
これは、次の標準機能として含まれています。
https://github.com/goktugyil/EZSwiftExtensions
免責事項:その私のレポ
最新Swift:
func detectScreenShot(action: @escaping () -> ()) {
let mainQueue = OperationQueue.main
NotificationCenter.default.addObserver(forName: .UIApplicationUserDidTakeScreenshot, object: nil, queue: mainQueue) { notification in
// executes after screenshot
action()
}
}
viewDidLoadで、この関数を呼び出します
detectScreenShot { () -> () in
print("User took a screen shot")
}
しかしながら、
NotificationCenter.default.addObserver(self, selector: #selector(test), name: .UIApplicationUserDidTakeScreenshot, object: nil)
func test() {
//do stuff here
}
まったく問題なく動作します。 mainQueueのポイントが表示されません...
ユーザーがhome + power button
をタップしたかどうかを検出する直接的な方法はないようです。 this に従って、以前はdarwin通知を使用することで可能になりましたが、もう機能しません。 snapchatはすでにそれを行っているので、私の推測では、iPhoneフォトアルバムをチェックして、この10秒の間に追加された新しい画像があるかどうかを検出し、何らかの形で表示されている現在の画像と比較しています。この比較のために画像処理が行われている可能性があります。ちょっと考えてみて、おそらくこれを拡張して機能させることができます。 詳細はこちら を確認してください。
編集:
UITouchキャンセルイベント(スクリーンキャプチャがタッチをキャンセルする)を検出し、このブログに従ってユーザーにこのエラーメッセージを表示しているようです: iOS(SnapChatなど)でスクリーンショットを検出する方法
その場合、– touchesCancelled:withEvent:
メソッドを使用してUITouchのキャンセルを検知し、これを検出できます。このデリゲートメソッドで画像を削除し、ユーザーに適切なアラートを表示できます。
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesCancelled:touches withEvent:event];
NSLog(@"Touches cancelled");
[self.imageView removeFromSuperView]; //and show an alert to the user
}
Swift 4の例
例#1クロージャを使用する
NotificationCenter.default.addObserver(forName: .UIApplicationUserDidTakeScreenshot,
object: nil,
queue: OperationQueue.main) { notification in
print("\(notification) that a screenshot was taken!")
}
セレクターを使用した例#2
NotificationCenter.default.addObserver(self,
selector: #selector(screenshotTaken),
name: .UIApplicationUserDidTakeScreenshot,
object: nil)
@objc func screenshotTaken() {
print("Screenshot taken!")
}