Skip to content

Instantly share code, notes, and snippets.

@BekNaji
Created June 12, 2025 05:51
Show Gist options
  • Save BekNaji/8170cf40479546dbc0f56b3bb5164a1b to your computer and use it in GitHub Desktop.
Save BekNaji/8170cf40479546dbc0f56b3bb5164a1b to your computer and use it in GitHub Desktop.
pretend screenshot in flutter
import UIKit
import Flutter
@main
@objc class AppDelegate: FlutterAppDelegate {
var eventSink: FlutterEventSink?
var field = UITextField()
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
let result = super.application(application, didFinishLaunchingWithOptions: launchOptions)
let controller = window.rootViewController as! FlutterViewController
let eventChannel = FlutterEventChannel(name: "screen_capture_event", binaryMessenger: controller.binaryMessenger)
eventChannel.setStreamHandler(self)
NotificationCenter.default.addObserver(
self,
selector: #selector(handleScreenCaptureChange),
name: UIScreen.capturedDidChangeNotification,
object: nil
)
addSecuredView()
return result
//return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
override func applicationWillResignActive(_ application: UIApplication) {
field.isSecureTextEntry = false
}
override func applicationDidBecomeActive(_ application: UIApplication) {
field.isSecureTextEntry = true
}
private func addSecuredView() {
if (!window.subviews.contains(field)) {
window.addSubview(field)
field.centerYAnchor.constraint(equalTo: window.centerYAnchor).isActive = true
field.centerXAnchor.constraint(equalTo: window.centerXAnchor).isActive = true
window.layer.superlayer?.addSublayer(field.layer)
if #available(iOS 17.0, *) {
field.layer.sublayers?.last?.addSublayer(window.layer)
} else {
field.layer.sublayers?.first?.addSublayer(window.layer)
}
}
}
@objc func handleScreenCaptureChange() {
let isCaptured = UIScreen.main.isCaptured
eventSink?(isCaptured)
}
@objc func userDidTakeScreenshot() {
print("📸 Screenshot detected!")
eventSink?(true)
}
}
extension UIWindow {
func makeSecure() {
let secureField = UITextField()
secureField.isSecureTextEntry = true
secureField.isHidden = true
self.addSubview(secureField)
secureField.translatesAutoresizingMaskIntoConstraints = false
secureField.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
secureField.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
// Important: Add its layer to your window
self.layer.superlayer?.addSublayer(secureField.layer)
}
}
extension AppDelegate: FlutterStreamHandler {
func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? {
self.eventSink = events
events(UIScreen.main.isCaptured)
return nil
}
func onCancel(withArguments arguments: Any?) -> FlutterError? {
self.eventSink = nil
return nil
}
func sendDataToFlutter(data: Any) {
eventSink?(data)
}
}
class ScreenCaptureHandler: NSObject, FlutterStreamHandler {
var isCaptured: Bool
init(isCaptured: Bool) {
self.isCaptured = isCaptured
}
func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? {
events(isCaptured)
return nil
}
func onCancel(withArguments arguments: Any?) -> FlutterError? {
return nil
}
}
//class CustomViewController: UIViewController {
// private var sdkViewController: UIViewController?
//
// override func viewDidLoad() {
// super.viewDidLoad()
// view.backgroundColor = .white
//
// if let sdkVC = sdkViewController {
// addChild(sdkVC)
// view.addSubview(sdkVC.view)
// sdkVC.view.frame = view.bounds
// sdkVC.didMove(toParent: self)
// }
//
// let backButton = UIBarButtonItem(image: UIImage(systemName: "chevron.backward"), style: .plain, target: self, action: #selector(dismissViewController))
// backButton.tintColor = UIColor(hex: "#a30041")
// self.navigationItem.leftBarButtonItem = backButton
// self.navigationItem.title = "Чат"
// }
//
// @objc func dismissViewController() {
// self.dismiss(animated: true, completion: nil)
// }
//
// func setSDKViewController(_ viewController: UIViewController) {
// self.sdkViewController = viewController
// }
//}
//
//extension UIColor {
// convenience init?(hex: String) {
// var hexCleaned = hex.trimmingCharacters(in: .whitespacesAndNewlines).replacingOccurrences(of: "#", with: "")
// var rgb: UInt64 = 0
// Scanner(string: hexCleaned).scanHexInt64(&rgb)
// self.init(
// red: CGFloat((rgb & 0xFF0000) >> 16) / 255.0,
// green: CGFloat((rgb & 0x00FF00) >> 8) / 255.0,
// blue: CGFloat(rgb & 0x0000FF) / 255.0,
// alpha: 1.0
// )
// }
//}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment