You do not have to create your button in the GameViewController, create it directly in your SKScene. It's not a good practice to use GameViewController for the user interface in SpriteKit games.
SpriteKit has many button tutorials.
As for ReplayKit, you can use it directly in the SKScene you want, just grab the code you already have and move it to the corresponding scene.
To represent the view controller in SKScene, you can say this
view?.window?.rootViewController?.present(unwrappedPreview, animated: true)
I also noticed that you are presenting a View controller after stopping recording. Are you sure you want to do this? Usually you have a separate menu button in your game where you can watch the recording.
Here is the generic code. I also recommend that you check the apples DemoBots game example.
I personally use the Singleton class to write managers, so its a lighter manager that calls all the methods you need for different scenes. To start class masonry, enter a new quick file and add this code.
class ScreenRecoder: NSObject {
To start recording, add this method to the ScreenRecorder class.
func start() { let sharedRecorder = RPScreenRecorder.shared() // Do nothing if screen recording is not available guard sharedRecorder.isAvailable else { return } // Stop previous recording if necessary if sharedRecorder.isRecording { stopScreenRecording() } print("Starting screen recording") // Register as the recorder delegate to handle errors. sharedRecorder.delegate = self // Start recording if
To stop recording, call this. You noticed that I do not show a preview yet, I just store it for later use. This is the usual way you do it.
func stop() { let sharedRecorder = RPScreenRecorder.shared() // Do nothing if screen recording is not available guard sharedRecorder.isAvailable else { return } // Stop recording sharedRecorder.stopRecording { [unowned self] (previewViewController, error) in if let error = error { // If an error has occurred, display an alert to the user. print(error.localizedDescription) // Show alert return } print("Stop screen recording") if let previewViewController = previewViewController { // Set delegate to handle view controller dismissal. previewViewController.previewControllerDelegate = self self.previewViewController = previewViewController } } }
Then create 2 extensions in the ScreenRecorder class that correspond to the ReplayKit delegates.
Preview Manager Delegate
/// RPPreviewViewControllerDelegate extension ScreenRecorder: RPPreviewViewControllerDelegate { /// Preview controller did finish func previewControllerDidFinish(_ previewController: RPPreviewViewController) { previewController.dismiss(animated: true, completion: nil) } }
and delegate entries
extension ScreenRecorder: RPScreenRecorderDelegate {
And finally, create a preview view method. You usually call this through a button in your game through the menu.
func showPreview() { guard let previewViewController = previewViewController else { return } print("Showing screen recording preview") // `RPPreviewViewController` only supports full screen modal presentation. previewViewController.modalPresentationStyle = .fullScreen let rootViewController = UIApplication.shared.keyWindow?.rootViewController rootViewController?.present(previewViewController, animated: true, completion:nil) }
Now you can call methods anywhere in your project
ScreenRecorder.shared.start() ScreenRecorder.shared.stop() ScreenRecorder.shared.showPreview() // call stop before calling this
This code is pretty much straight from DemoBots.
I think the best way to handle recording on the screen is to create an auto record button in the main menu. Use UserDefaults to save on / off status. If it is on, you call startRecording when your gameplay begins, and cause it to stop recording when the game ends. Then you show the preview button in your game through the menu to see the recording if the user wants.
Hope this helps