App StoreにあるアプリSnapchatは、写真を自己破壊して共有できるアプリです。写真はX秒間しか表示できません。家庭用電源キーの組み合わせを使用して画像が表示されているときにスクリーンショットを撮ろうとすると、スクリーンショットを撮ろうとしたことが送信者に通知されます。
SDKのどの部分で、ユーザーがスクリーンショットを撮っていることを検出できますか?これが可能であることを知りませんでした。
App StoreにあるアプリSnapchatは、写真を自己破壊して共有できるアプリです。写真はX秒間しか表示できません。家庭用電源キーの組み合わせを使用して画像が表示されているときにスクリーンショットを撮ろうとすると、スクリーンショットを撮ろうとしたことが送信者に通知されます。
SDKのどの部分で、ユーザーがスクリーンショットを撮っていることを検出できますか?これが可能であることを知りませんでした。
回答:
答えを見つけた!! スクリーンショットを撮ると、画面上のすべてのタッチが中断されます。これが、snapchatが写真を表示するために長押しする必要がある理由です。リファレンス:http : //tumblr.jeremyjohnstone.com/post/38503925370/how-to-detect-screenshots-on-ios-like-snapchat
iOS 7以降、他の答えは当てはまりません。Appleが作成したためtouchesCancelled:withEvent:
、ユーザーがスクリーンショットを撮ったときに呼び出されることはありません。
これは効果的にSnapchatを完全に破壊するため、新しいソリューションのベータ版がいくつか追加されました。これで、ソリューションはNSNotificationCenterを使用してオブザーバーをUIApplicationUserDidTakeScreenshotNotificationに追加するのと同じくらい簡単です。
次に例を示します。
NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];
[[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationUserDidTakeScreenshotNotification
object:nil
queue:mainQueue
usingBlock:^(NSNotification *note) {
// executes after screenshot
}];
NotificationCenter.default.addObserver(
forName: UIApplication.userDidTakeScreenshotNotification,
object: nil,
queue: .main) { notification in
//executes after screenshot
}
touchesCancelled:withEvent:
、iOSのすべての(最近の)バージョンでスクリーンショットを検出できます。
クロージャーを使用して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 3:
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
です。あたりとして、この、それはダーウィンの通知を使用して、以前可能であったが、それはもはや動作しません。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
}
Home + Lock
ボタンを押すと、OSはすぐに指が画面に触れていないかのように動作するという事実に関連しています。おそらくこれはtouchesEnded:withEvent
通常のように(または類似のコールバック)なしで発生するので、おそらくこのユニークなイベントパターンを監視できますか?私は完全に間違った軌道に乗っているかもしれませんが、それは現時点で私の唯一の理論です。
スウィフト4+
NotificationCenter.default.addObserver(forName: UIApplication.userDidTakeScreenshotNotification, object: nil, queue: OperationQueue.main) { notification in
//you can do anything you want here.
}
このオブザーバーを使用することで、ユーザーがスクリーンショットを撮るタイミングを知ることができますが、ユーザーを防ぐことはできません。
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!")
}